7

We are required in our assignment to find the second smallest integer in one array recursively. However, for the sake of understanding the subject more, I want to do it iteratively first (with the help of this website) and recursively on my own.

Unfortunately, doing it iteratively is quite confusing. I understand that the solution is simple but i can't wrap my head around it.

Below is my code, so far:

public static void main(String[] args) 
{
    int[] elements  = {0 , 2 , 10 , 3, -3 }; 
    int smallest = 0; 
    int secondSmallest = 0; 

    for (int i = 0; i < elements.length; i++)
    {
        for (int j = 0; j < elements.length; j++)
        {
            if (elements[i] < smallest)
            {
                smallest = elements[i];

                if (elements[j] < secondSmallest)
                {
                    secondSmallest = elements[j];
                }
            }
        }

    }

    System.out.println("The smallest element is: " + smallest + "\n"+  "The second smallest element is: " + secondSmallest);
}

This works for a few numbers, but not all. The numbers change around because the inner if condition isn't as efficient as the outer if condition.

Array rearrangements are forbidden.

2
  • 1
    You shouldn't initialize smallest with 0 if the array might contain only numbers greater than that. Try int smallest = Integer.MAX_VALUE for a start. Same goes for secondSmallest. Commented May 24, 2015 at 20:20
  • Alternatively, elements[0] is a suitable initialization for smallest and secondSmallest, since that is a candidate for the smallest in the array. Commented May 24, 2015 at 20:35

21 Answers 21

15

Try this one. Second condition is used to catch an event when the smallest number is the first

    int[] elements = {-5, -4, 0, 2, 10, 3, -3};
    int smallest = Integer.MAX_VALUE;
    int secondSmallest = Integer.MAX_VALUE;
    for (int i = 0; i < elements.length; i++) {
        if(elements[i]==smallest){
          secondSmallest=smallest;
        } else if (elements[i] < smallest) {
            secondSmallest = smallest;
            smallest = elements[i];
        } else if (elements[i] < secondSmallest) {
            secondSmallest = elements[i];
        }

    }

UPD by @Axel

int[] elements = {-5, -4, 0, 2, 10, 3, -3};
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
for (int i = 0; i < elements.length; i++) {
    if (elements[i] < smallest) {
        secondSmallest = smallest;
        smallest = elements[i];
    } else if (elements[i] < secondSmallest) {
        secondSmallest = elements[i];
    }
}
Sign up to request clarification or add additional context in comments.

8 Comments

What is the expected result when two numbers have the smallest value? For example when int[] elements = {-5, -4, 0, 2, 10, 3, -5}? Should it be -5 or -4? This one gives you -4.
Wouldn't it be enough to use => instead of > in the second if? (Oh, sorry, now it's the third.)
So better just remove the first ifand the whole && elements[i] > smallest to make it more readable.
For the input int[] elements = {-5, -4, 0, 2, 10, 3, -5} we should get -4 as second smallest number. In that case else if (elements[i] < secondSmallest && elements[i] != smallest) { secondSmallest = elements[i]; }
what if array has only sigle value? int [] arr = {0}, then it fails, returns the Max_VALUE
|
3

Here is TimeComlexity Linear O(N):

  public static int secondSmallest(int[] arr) {
    if(arr==null || arr.length < 2) {
        throw new IllegalArgumentException("Input array too small");
    }

    //implement
    int firstSmall = -1;
    int secondSmall = -1;

    //traverse to find 1st small integer on array
    for (int i = 0; i<arr.length;i++)
        if (firstSmall == -1 || arr[firstSmall]>arr[i])
            firstSmall = i;

     //traverse to array find 2 integer, and skip first small
    for (int i = 0;i<arr.length;i++) {
        if (i != firstSmall && (secondSmall == -1 || arr[secondSmall] > arr[i]))
            secondSmall = i;
    }

    return arr[secondSmall];
}

Comments

2
    int[] arr = { 4, 1, 2, 0, 6, 1, 2, 0 };

    int smallest = Integer.MAX_VALUE;
    int smaller = Integer.MAX_VALUE;
    int i = 0;

    if (arr.length > 2) {
        for (i = 0; i < arr.length; i++) {

            if (arr[i] < smallest) {
                smaller = smallest;
                smallest = arr[i];
            } else if (arr[i] < smaller && arr[i] > smallest) {
                smaller = arr[i];
            }
        }

        System.out.println("Smallest number is " + smallest);
        System.out.println("Smaller number is " + smaller);

    } else {
        System.out.println("Invalid array !");
    }
}

1 Comment

what if array has only sigle value? int [] arr = {0}, then it fails, returns the Max_VALUE
2

You can do it in O(n) time. Below is the python code

def second_small(A):
    if len(A)<2:
        print 'Invalid Array...'
        return
    small = A[0]
    second_small = [1]
    if small >  A[1]:
        second_small,small = A[0],A[1]

    for i in range(2,len(A)):
        if A[i] < second_small and A[i]!=small:
            if A[i] < small:
                second_small = small
                small = A[i]
            else:
                second_small = A[i]
    print small, second_small
A = [12, 13, 1, 10, 34, 1]
second_small(A)

Comments

1
public static int findSecondSmallest(int[] elements) {
    if (elements == null || elements.length < 2) {
        throw new IllegalArgumentException();
    } 
    int smallest = elements[0]; 
    int secondSmallest = elements[0]; 
    for (int i = 1; i < elements.length; i++) {
        if (elements[i] < smallest) {
            secondSmallest = smallest;
            smallest = elements[i];
        } 
        else if (elements[i] < secondSmallest) {
            secondSmallest = elements[i];
        }
    }
    return secondSmallest;
}

2 Comments

This code is not going to work if there is an element that is >= smallest, however < secondSmallest. In this case, `secondSmallest should be replaced.
Also if first value in elements is smallest, it won't set secondSmallest
1

Simply, you can do this

int[] arr = new int[]{34, 45, 21, 12, 54, 67, 15};
Arrays.sort(arr);
System.out.println(arr[1]);

2 Comments

This is the shortest and the best solution, in my opinion but it is not recursive as described by the author of question ;)
Nope. It is wrong, if the 12 occurs more than once .
1

Try this one.

    public static void main(String args[]){
        int[] array = new int[]{10, 30, 15, 8, 20, 4};

        int min, secondMin;

        if (array[0] > array[1]){
            min = array[1];
            secondMin = array[0];
        }
        else{
            min = array[0];
            secondMin = array[1];
        }

        for (int i=2; i<array.length; i++){
            if (array[i] < min){
                secondMin = min;
                min = array[i];
            }
            else if ((array[i] > min) && (array[i] < secondMin)){
                secondMin = array[i];
            }
        }
       System.out.println(secondMin);
  }

Comments

1

I've used Sort function in javascript

function sumTwoSmallestNumbers(numbers){  
  numbers = numbers.sort(function(a, b){return a - b; });
  return numbers[0] + numbers[1];
};

by providing a compareFunction for the sort functionality array elements are sorted according to the return value of the function.

Comments

1

How about this?

   int[] result = Arrays.asList(-3, 4,-1,-2).stream()
            .reduce(new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE},
                    (maxValues, x) -> {
                        if (x > maxValues[0]) {
                            maxValues[1] = maxValues[0]; //max becomes second max
                            maxValues[0] = x;
                        }
                        else if (x > maxValues[1]) maxValues[1] = x;
                        return maxValues;
                    }
                    , (x, y) -> x);

Comments

1
class A{
    public static void main (String args[]){
        int array[]= {-5, -4, 0, 2, 10, 3, -3};
        int min;
        int second_min;
        if(array[0]<array[1]){
            min=array[0];
            second_min=array[1];
        }else{
            min=array[1];
            second_min=array[0];
        }
        for(int i=2;i<array.length;i++){
            if(second_min > array[i] && min > array[i]){
                    second_min=min;
                    min=array[i];                              
            }else  if(second_min > array[i] && min < array[i]){
                min=min;
                second_min=array[i];
            }
        }
        System.out.println(min);
        System.out.println(second_min);
    }
}

1 Comment

Please add some explanation.
1

Find the second minimum element of an array in Python, short and simple

def second_minimum(arr):
    second = arr[1]
    first = arr[0]

    for n in arr:
        if n < first:
            first = n
        if n > first and n < second  :
            second = n

    return second

print(second_minimum([-2, 4, 5, -1, 2, 3, 0, -4, 1, 99, -6, -5, -19]))

Comments

0
     public static void main(String[] args) 
{
    int[] elements  = {-4 , 2 , 10 , -2, -3 }; 
    int smallest = Integer.MAX_VALUE; 
    int secondSmallest = Integer.MAX_VALUE; 

    for (int i = 0; i < elements.length; i++)
    {
        if (smallest>elements[i])
            smallest=elements[i];

    }

    for (int i = 0; i < elements.length; i++)
    {
        if (secondSmallest>elements[i] && elements[i]>smallest)
            secondSmallest=elements[i];

    }

    System.out.println("The smallest element is: " + smallest + "\n"+  "The second smallest element is: " + secondSmallest);
}

1 Comment

this will work on arrays with duplicates as well ,, like int[] elements = {-4 , -4 , -4 , -4, -3 };
0
public static void main(String[] args) {

    Scanner in = new Scanner(System.in);
    System.out.println("Enter array size = ");
    int size=in.nextInt();
    int[] n = new int[size];
    System.out.println("Enter "+ size +" values ");

    for(int i=0;i<n.length;i++)
        n[i] = in.nextInt();
    int small=n[0],ssmall=n[0];

    // finding small and second small
    for(int i=0;i<n.length;i++){
        if(small>n[i]){
            ssmall=small;
            small=n[i];
            }else if(ssmall>n[i])
                ssmall=n[i];
    }

    // finding second small if first element itself small
    if(small==n[0]){
        ssmall=n[1];
        for(int i=1;i<n.length;i++){
            if(ssmall>n[i]){
                ssmall=n[i];
                }
        }
    }

    System.out.println("Small "+ small+" sSmall "+ ssmall);

    in.close();
}

Comments

0
public static void main(String[] args)  {
    int arr[] = {6,1,37,-4,12,46,5,64,21,2,-4,-3};
    int lowest =arr[0];
    int sec_lowest =arr[0];
    for(int n : arr){
        if (lowest >  n)
        {
            sec_lowest = lowest;
            lowest = n;

        }
        else if (sec_lowest > n && lowest != n)
            sec_lowest = n;
    }

    System.out.println(lowest+"   "+sec_lowest);

    }

1 Comment

From review queue: May I request you to please add some more context around your answer. Code-only answers are difficult to understand. It will help the asker and future readers both if you can add more information in your post.
0

enter image description here

public class SecondSmallestNumberInArray 
        {
            public static void main(String[] args) 
            {
                int arr[] = { 99, 76, 47, 85, 929, 52, 48, 36, 66, 81, 9 };
                int smallest = arr[0];
                int secondSmallest = arr[0];

                System.out.println("The given array is:");
                boolean find = false;
                boolean flag = true;

                for (int i = 0; i < arr.length; i++) 
                {
                    System.out.print(arr[i] + "  ");
                }

                System.out.println("");

                while (flag) 
                {
                    for (int i = 0; i < arr.length; i++) 
                    {
                        if (arr[i] < smallest) 
                        {   
                            find = true;
                            secondSmallest = smallest;
                            smallest = arr[i];
                        } else if (arr[i] < secondSmallest) {   
                            find = true;
                            secondSmallest = arr[i];
                        }
                    }
                    if (find) {
                        System.out.println("\nSecond Smallest number is Array : ->  " + secondSmallest);
                        flag = false;
                    } else {
                        smallest = arr[1];
                        secondSmallest = arr[1];
                    }
                }
            }
        }

    **Output is**

    D:\Java>java SecondSmallestNumberInArray

    The given array is:

    99  76  47  85  929  52  48  36  66  81  9

    Second Smallest number is Array : ->  36

    D:\Java>

2 Comments

explain it please
Muhammad Muazzam Dry Run this code very simple step Need to check if else statement
0
public static int getSecondSmallest(int[] arr){
        int smallest = Integer.MAX_VALUE;
        int secondSmallest = Integer.MAX_VALUE;
        for(int i=0;i<arr.length;i++){
            if(smallest > arr[i]){
                secondSmallest = smallest;
                smallest = arr[i];
            }else if (secondSmallest > arr[i] && arr[i] != smallest){
            secondSmallest = arr[i];
        }
            System.out.println(i+" "+smallest+" "+secondSmallest);
        }
        return secondSmallest;
    }

Just gave it a try with some of the test cases and it worked. Please check if it is correct!

Comments

0

Try this ... First condition checks if both values are less than value in array. Second condition if value is less than small than smallest=element[i] else secondSmallest=elements[i]..

public static void main(String[] args) 
{
    int[] elements  = {0 , 2 , 10 , 3, -3 }; 
    int smallest = elements[0];
    int secondSmallest = 0; 

      for (int i = 0; i < elements.Length; i++)
        {
            if (elements[i]<smallest || elements[i]<secondSmallest )
            {
                if (elements[i] < smallest )
                {
                    secondSmallest  = smallest ;
                    smallest = elements[i];

                }
                else
                {
                    secondSmallest = elements[i];

                }
            }
        }

    System.out.println("The smallest element is: " + smallest + "\n"+  "The second smallest element is: " + secondSmallest);
}

Comments

0

Try this, program gives solution for both lowest value and second lowest value of array.

Initialize min and second_min with first element of array.Find out the min value and compare it with second_min value . If it (second_min) is greater than current element of array and min value then the second_min value replace with current element of array.

In case arr[]={2,6,12,15,11,0,3} like this , temp variable used to store previous second_min value.

public class Main
    {
        public static void main(String[] args) {
            //test cases.
            int arr[]={6,12,1,11,0};
            //int arr[]={0,2,10,3,-3}; 
            //int arr[]={0,0,10,3,-3}; 
            //int arr[]={0,2 ,10, 3,-3}; 
            //int arr[]={12,13,1,10,34,1};
            //int arr[]={2,6,12,15,11,0,3};
            //int arr[]={2,6,12,15,1,0,3};
            //int arr[]={2,6,12,15};
            //int arr[]={0,1};
            //int arr[]={6,16};
            //int arr[]={12};
            //int arr[]={6,6,6,6,6,6};
            int position_min=0;
            int min=arr[0];int second_min=arr[0]; int temp=arr[0];
            if(arr.length==1)
            {
                System.out.println("Lowest value is "+arr[0]+"\n Array length should be greater than 1. ");
            }
            else if(arr.length==2)
            {
                if(arr[0]>arr[1])
                {
                    min=arr[1];
                    second_min=arr[0];
                    position_min=1;
                }
                else
                {
                    min=arr[0];
                    second_min=arr[1];
                    position_min=0;
                }
                System.out.println("Lowest value is "+min+"\nSecond lowest value is "+second_min);
            }
            else
            {
                for( int i=1;i<arr.length;i++)
                {
                   if(min>arr[i])
                   {
                       min=arr[i];
                       position_min=i;
                   }
                }
                System.out.println("Lowest value is "+min);
                for(int i=1;i<arr.length;i++)
                {
                    if(position_min==i)
                    {

                    }
                    else
                    {
                         if(second_min > min & second_min>arr[i])
                         {
                             temp=second_min;
                             second_min=arr[i];
                         }
                         else if(second_min == min )
                         {
                             second_min=arr[i];
                         }
                    }
                }

                if(second_min==min )
                {
                    second_min=temp;
                }
                //just for message if in case all elements are same in array.
                if(temp==min && second_min==min)
                {
                    System.out.println("There is no Second lowest element in array.");
                }
                else{
                    System.out.println("\nSecond lowest value is "+second_min);
                }

            }

    }
    }

Comments

0

Here's a Swift version that runs in linear time. Basically, find the smallest number. Then assign the 2nd minimum number as the largest value. Then loop through through the array and find a number greater than the smallest one but also smaller than the 2nd smallest found so far.

func findSecondMinimumElementLinear(in nums: [Int]) -> Int? {
    // If the size is less than 2, then returl nil.
    guard nums.count > 1 else { return nil }

    // First, convert it into a set to reduce duplicates.
    let uniqueNums = Array(Set(nums))

    // There is no point in sorting if all the elements were the same since it will only leave 1 element
    // after the set removed duplicates.
    if uniqueNums.count == 1 { return nil }

    let min: Int = uniqueNums.min() ?? 0 // O(n)
    var secondMinNum: Int = uniqueNums.max() ?? 0 // O(n)
    // O(n)
    for num in uniqueNums {
        if num > min && num < secondMinNum {
            secondMinNum = num
        }
    }

    return secondMinNum
}

Comments

0

a straight forward solution in lambda

int[] first = {Integer.MAX_VALUE};
int rslt = IntStream.of( elements ).sorted().dropWhile( n -> {
    boolean b = n == first[0] || first[0] == Integer.MAX_VALUE;
    first[0] = n;
    return( b );
} ).findFirst().orElse( Integer.MAX_VALUE );

the returned OptionalInt from findFirst() can be used to handle the special cases
for elements.length < 2 or elements containing only one value several times
here Integer.MAX_VALUE is returned, if there is no second smallest integer

Comments

0

Well, that should work for you:

function getSecondMin(array){
  if(array.length < 2) return NaN;

  let min = Math.min(array[0],array[1]);
  let secondMin = Math.max(array[0],array[1])

  for (let i = 2; i < array.length; i++) {
      if(array[i]< min){
        secondMin = min
        min = array[i]
      }
      else if(array[i] < secondMin){
        secondMin = array[i]
      }    
  }
  return secondMin;
}

const secondMin = getSecondMin([1,4,3,100,2])
console.log(secondMin || "invalid array length");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.