88 */ 
99public  class  NthSmallestNumber  {
1010
11+     /** 
12+      * Given an unsorted array of integers, find the nth smallest integer in the array in most optimized way possible. 
13+      * <p> 
14+      * Approach: Similar to Quick Sort where in every iteration, we choose a pivot element and shift all lesser integers 
15+      * to left and higher integers to the right. After doing this we compare the pivot index with n and recursively call 
16+      * the method accordingly. See {@link com.rampatra.sorting.QuickSort}. 
17+      * 
18+      * @param arr   the input unsorted array of integers 
19+      * @param n     nth smallest integer to find 
20+      * @param start the start index in the array to search (inclusive) 
21+      * @param end   the last index in the array to search (inclusive) 
22+      * @return the nth smallest integer, {@code -1} if invalid input 
23+      */ 
1124    private  static  int  findNthSmallestNumber (int [] arr , int  n , int  start , int  end ) {
1225        if  (arr .length  == 0  || arr .length  < n ) {
1326            return  -1 ;
1427        }
1528        int  temp ;
29+         int  lastBigger  = start ;
1630        for  (int  i  = start ; i  < end ; i ++) {
1731            if  (arr [i ] < arr [end ]) {
1832                temp  = arr [i ];
19-                 arr [i ] = arr [start ];
20-                 arr [start ] = temp ;
21-                 start ++;
33+                 arr [i ] = arr [lastBigger ];
34+                 arr [lastBigger ] = temp ;
35+                 lastBigger ++;
2236            }
2337        }
24-         temp  = arr [end ];
25-         arr [end ] = arr [start ];
26-         arr [start ] = temp ;
38+         temp  = arr [lastBigger ];
39+         arr [lastBigger ] = arr [end ];
40+         arr [end ] = temp ;
2741
28-         if  (start  + 1  < n ) {
29-             return  findNthSmallestNumber (arr , n , 0 ,  start );
30-         } else  if  (start  + 1  > n ) {
31-             return  findNthSmallestNumber (arr , n , start  +  1 ,  end );
42+         if  (lastBigger  + 1  < n ) {
43+             return  findNthSmallestNumber (arr , n , lastBigger  +  1 ,  end );
44+         } else  if  (lastBigger  + 1  > n ) {
45+             return  findNthSmallestNumber (arr , n , start ,  lastBigger  -  1 );
3246        } else  {
33-             return  arr [start ];
47+             return  arr [lastBigger ];
3448        }
3549    }
3650
@@ -41,7 +55,7 @@ public static void main(String[] args) {
4155        System .out .println (findNthSmallestNumber (new  int []{1 , 0 }, 2 , 0 , 1 ));
4256        System .out .println (findNthSmallestNumber (new  int []{2 , 3 , 5 , 10 , 9 , 4 }, 3 , 0 , 5 ));
4357        System .out .println (findNthSmallestNumber (new  int []{2 , 3 , 4 , 10 , 9 , 4 }, 3 , 0 , 5 ));
44-         System .out .println (findNthSmallestNumber (new  int []{4 , 8 ,  1 ,  9 ,  10 ,  2 ,  7 ,  3 ,  2 ,  6 }, 3 , 0 , 9 ));
45- //         System.out.println(findNthSmallestNumber(new int[]{4, 4, 4, 4, 4, 4 }, 3, 0, 5 ));
58+         System .out .println (findNthSmallestNumber (new  int []{4 , 4 ,  4 ,  4 ,  4 ,  4 }, 3 , 0 , 5 ));
59+         System .out .println (findNthSmallestNumber (new  int []{4 , 8 ,  1 ,  9 ,  10 ,  2 ,  7 ,  3 ,  2 ,  6 }, 3 , 0 , 9 ));  // TODO: doesn't work with duplicates currently 
4660    }
4761}
0 commit comments