Quick Sort/Select
Quick select/Partition
给定array和一个数K,
要求把<K的数都放到K的左边,>=K 的数都放到K的右边
返回partition后从左到右第一个K所在的index
这题是partition的基本功
建立两个runner pointer, left and right, while loop
left用来找下一个>=k的数,right找下一个<K的数,然后交换, 直到left > right
这样array就被partition成了两部分,左边部分都是<K的数,right是最后一个。右边部分都是>=K的数,left就是右边部分的起始位置
注:标准的partition 是把array分成3部分,左边部分< K, 右边部分> K, 中间可能有n个 重复的K。这样判断条件就只是nums[begin] < k和nums[end] > k,不加"<="或者">="
public int partitionArray(int[] nums, int k) {
if (nums == null || nums.length < 1) {
return 0;
}
int begin = 0, end = nums.length - 1;
while (begin <= end) {
while (begin <= end && nums[begin] < k) {
begin++;
}
while (begin <= end && nums[end] >= k) {
end--;
}
if (begin<= end) {
swap(nums, begin, end);
begin++;
end--;
}
}
return begin;
}
private void swap(int[] nums, int begin, int end) {
int tmp = nums[begin];
nums[begin] = tmp;
nums[end] = nums[begin];
}
这题如果面试遇到,想到最优解Quick select之前应该先讨论sort and heap的两种解法
把array partition成3部分,左边部分< K, 右边部分> K, 中间可能有n个 重复的K。这样判断条件就只是nums[begin] < k和nums[end] > k,不加"<="或者">="
Partition Array
class Solution {
public int findKthLargest(int[] nums, int k) {
return quickSelect(nums, 0, nums.length - 1, nums.length - k);
}
//quickSelect, return value
private int quickSelect(int[] nums, int begin, int end, int k) {
if (begin >= end) {
return nums[k];
}
int left = begin, right = end;
int pivot = nums[(begin + end) / 2];
while (left <= right) {
while (left <= right && nums[left] < pivot) {
left++;
}
while (left <= right && nums[right] > pivot) {
right--;
}
if (left <= right) {
swap(nums, left, right);
left++;
right--;
}
}
if (k <= right) {
return quickSelect(nums, begin, right, k);
}
if (k >= left) {
return quickSelect(nums, left, end, k);
}
return nums[k];
}
private void swap(int[] nums, int begin, int end) {
int tmp = nums[begin];
nums[begin] = nums[end];
nums[end] = tmp;
}
}
Last updated
Was this helpful?