quicksort liner find kth smallest or

 
  
Let's solve a problem with application of quick sort.
 
  

Problem statement 

Given an set of numbers in non-sorted order, find the Kth smallest element.
 
  
Kth smallest element means there are N-K-1 elements in set which are greater than the desired element.
 
  

Analysis

 
  
We can solve this problem in two simple steps:
 
  
1. sort the input set.
 
  
2. Scan the array till Kth element, it gives us the Kth smallest element.
 
  
 
 
  
Thing to ponder upon here is can we do better? Can we avoid the second step? Can we reduce the size of input to be sorted or not sorting the input at all?
 
  
 
 
  
Answer to all above questions is Yes. Think Quick sort.
 
  

Algorithm

 
  
Quick sort does not completely sorts two sub arrays when it gives us the correct position of pivot.By property of quick sort we know that all elements which are on left side of pivot are less than pivot.
 
  
Let's say we have pivot swapped with jth element of the input set, so there are j elements which are less than pivot. Can we use this information to find Kth element? Absolutely yes.
 
  
 
 
  
If  j is less than K, then we have smaller left subset and we need to  look into right subset of the input to get the Kth smallest element. So we look (K-j)th smallest element in the right subset.
 
  
Here we have not sorted left or right subset of the input and still we reduced the candidate by almost half.
 
  
 
 
  
If  j is more than K, then we need to  look in left subset of input. Here we have discarded the right subset of the input.

 
  
As we are doing partitions and calculating the position of pivot, we don't need to scan the array afterwards. As soon as position of pivot is equal to K, we got element.
 
  




Example 

Let's say we have an array with following elements 4,2,1,7,5,3,8,10,9,6 and we need to find fifth smallest element in this array. In this example output will be 5.






We have pivot as 1st element i.e 4 and we divide the remaining array in such a way that we find the correct position of 4.
Once 4 is in correct position, all the elements on  left side are less than pivot i.e 4 and on  right side, are greater than pivot.
Now check the position of pivot, if it is K-1 (array is represented as zero base index), then pivot is our element.
Here final position of 4 after first execution of quick sort function will be index 3.



Since pivot position is less than K-1 i.e 4, we need to look for element in right side of the pivot.
Notice that we are not reducing K as pivot position is given w.r.t whole array and not w.r.t sub-array under consideration.
 
In second iteration, 5 will be pivot. After second execution of quick sort array will look as mentioned above only thing is our pivot position is change.




pivot index is now 4 which is equal to K-1. Hence our 5th smallest element in this array is 5. Note that we have not sorted the complete array.






import
java.util.Comparator; import java.util.PriorityQueue; public class solution2 { public static void main(String[] args) { // TODO Auto-generated method stub int A[] = {3,4,6,3,5,33,8,6,4,3,2,1,4,0,3}; quickSort(A,0,A.length-1,3); for(int i : A){ System.out.println(i); } } static void swap(int[] A, int i, int j){ int temp = A[i]; A[i] = A[j]; A[j] = temp; return; } public static void quickSort(int[] array, int start, int end, int k) { if (start < end) { int part = partion(array, start, end); if(part == (k-1)){ System.out.println("kth = " + array[part]); } if(part > k-1) quickSort(array, start, part,k); else { quickSort(array, part+1, end,k); } } } private static int partion(int[] n, int start, int end) { int tmp = n[start]; while (start < end) { while (n[end] >= tmp && start < end) end--; if (start < end) { n[start++] = n[end]; } while (n[start] < tmp && start < end) start++; if (start < end) { n[end--] = n[start]; } } n[start] = tmp; return start; } }

 

转载于:https://www.cnblogs.com/leetcode/p/3551417.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值