Kth Largest Element
Find K-th largest element in an array.
Note
You can swap elements in the array
Example
In array [9,3,2,4,8], the 3th largest element is 4
Challenge
O(n) time, O(1) space
原题链接:
http://www.lintcode.com/en/problem/kth-largest-element/
SOLUTION 1:
使用改进的Quicksort partition,可以达到O(n)的时间复杂度,并且不需要额外空间。
请参考: http://en.wikipedia.org/wiki/Quickselect#Time_complexity
时间复杂度:如果我们是这样的数组:1,2,3,4,5,然后又每一次取左边的当pivot,就会达到最坏的时间复杂度。也就是O(N2)
我们也有一些解决方法:
以下来自维基,我们可以取3个数进行平均。
http://stackoverflow.com/questions/7559608/median-of-three-values-strategy
The easiest solution is to choose a random pivot, which yields almost certain linear time. Deterministically, one can use median-of-3 pivot strategy (as in the quicksort), which yields linear performance on partially sorted data, as is common in the real world. However, contrived sequences can still cause worst-case complexity; David Musser describes a "median-of-3 killer" sequence that allows an attack against that strategy, which was one motivation for his introselect algorithm.
1 package Algorithms.algorithm.NChapter.findKthNumber; 2 3 import java.util.ArrayList; 4 5 // The link: 6 7 // http://www.lintcode.com/en/problem/kth-largest-element/ 8 9 class KthLargestElement_lintCode { 10 //param k : description of k 11 //param numbers : array of numbers 12 //return: description of return 13 public int kthLargestElement(int k, ArrayList<Integer> numbers) { 14 // write your code here 15 if (k < 1 || numbers == null) { 16 return 0; 17 } 18 19 return getKth(numbers.size() - k + 1, numbers, 0, numbers.size() - 1); 20 } 21 22 public int getKth(int k, ArrayList<Integer> numbers, int start, int end) { 23 // Choose the last one as the pivot 24 int pivot = numbers.get(end); 25 26 int left = start; 27 int right = end; 28 29 while (true) { 30 while (numbers.get(left) < pivot && left < right) { 31 left++; 32 } 33 34 while (numbers.get(right) >= pivot && right > left) { 35 right--; 36 } 37 38 if (left == right) { 39 break; 40 } 41 42 swap(numbers, left, right); 43 } 44 45 // left: the first one which is bigger than pivot. 46 swap(numbers, left, end); 47 48 if (k == left + 1) { 49 return pivot; 50 // Try to find the element from the left side. 51 } else if (k < left + 1) { 52 return getKth(k, numbers, start, left - 1); 53 } else { 54 // Try to find the element from the right side. 55 return getKth(k, numbers, left + 1, end); 56 } 57 } 58 59 /* 60 Swap the two nodes. 61 */ 62 public void swap(ArrayList<Integer> numbers, int n1, int n2) { 63 int tmp = numbers.get(n1); 64 numbers.set(n1, numbers.get(n2)); 65 numbers.set(n2, tmp); 66 } 67 };
SOLUTION 2:
以下这些链接有详细的讨论,就不再一一叙述了。目前来讲Solution 1应该是最优的啦。
http://www.geeksforgeeks.org/k-largestor-smallest-elements-in-an-array/
http://www.quora.com/What-is-the-most-efficient-algorithm-to-find-the-kth-smallest-element-in-an-array-having-n-elements
GITHUB: