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
思路就是像快速排序一样partition,最后pivot的位置决定是向左还是右继续partition。
归纳一下partition的算法:
1. random select a pivot,这里我们选择最后一个值
2. 左右指针分别扫,如果left pointer >= pivot, right pointer < pivot,说明两个需要互换
3. 然后接着再扫
4.最后pivot 和left pointer互换,因为left pointer的位置就是第一个>= pivotd的值存在的位置,所以两个换了之后pivot新位置两边是被sort了
一个问题出在没看清题意,kth larges vs. kth smallest
Update:
自己比较容易理解的做法:
public int kthLargestElement(int k, ArrayList<Integer> numbers) {
return partition(n-k, numbers, 0, numbers.size()-1);
}
<strong>
</strong> int partition(int k, ArrayList<Integer> numbers, int start, int end) {
int wall = numbers.get(end);
int left = start;
int right = end-1;
while (left <= right) {
while (left <= right && numbers.get(left) <= wall) { // at least left or right should consider the "==" condition
left++;
}
while (right >= left && numbers.get(right) > wall) {
right--;
}
if (left >= right) {
break;
}
int tmp = numbers.get(left);
numbers.set(left, numbers.get(right));
numbers.set(right, tmp);
left++;
right--;
}
numbers.set(end, numbers.get(left));
numbers.set(left, wall);
if (left == k) {
return wall;
} else if (left < k) {
return partition(k, numbers, left+1, end);
} else {
return partition(k, numbers, start, left-1);
}
}
public int kthLargestElement(int k, ArrayList<Integer> numbers) {
return helper(0, numbers.size()-1, numbers.size()-k+1, numbers);
}
int helper(int left, int right, int k, ArrayList<Integer> numbers) {
int pivot = numbers.get(right);
int low = left;
int high = right;
while (low < right) {
while (low < high && numbers.get(low) < pivot) {
low++;
}
while (low < high && numbers.get(high) >= pivot) {
high--;
}
if (low == high) {
break;
}
swap(low, high, numbers);
}
swap(low, right, numbers);
if (low == k-1) {
return pivot;
} else if (low < k) {
return helper(low+1, right, k, numbers);
} else {
return helper(left, low-1, k, numbers);
}
}
void swap(int left, int right, ArrayList<Integer> numbers) {
int tmp = numbers.get(left);
numbers.set(left, numbers.get(right));
numbers.set(right, tmp);
}