1.快排,就是每个元素都归位,如果某一元素刚好在k位那他就是第k大
第一个元素temp 然后第1位为 i 最后一个为j 从j开始j--,如果遇到比temp大的应该在左边,放入i 然后i++,直到比temp小的应该放在右边 j的位置 然后继续j--, 直到 i=j
本题需要使用快速排序的思想,快速排序:每次移动,可以找到一个标杆元素,然后将大于它的移到左边,小于它的移到右边,由此整个数组划分成为两部分,然后分别对左边和右边使用同样的方法进行排序,不断划分左右子段,直到整个数组有序。这也是分治的思想,将数组分化成为子段,分而治之。
- step 1:进行一次快排,大元素在左,小元素在右,得到的中轴p点。
- step 2:如果 p - low + 1 = k ,那么p点就是第K大。
- step 3:如果 p - low + 1 > k,则第k大的元素在左半段,更新high = p - 1,执行step 1。
- step 4:如果 p - low + 1 < k,则第k大的元素在右半段,更新low = p + 1, 且 k = k - (p - low + 1),排除掉前面部分更大的元素,再执行step 1.
classSolution {
public:
//常规的快排划分,但这次是大数在左边
int partion(vector<int>& a, intlow, inthigh){
int temp = a[low];
while(low < high){
//小于标杆的在右
while(low < high && a[high] <= temp) // 交换完a【high 】一定大于temp 不然怎么会交换呢,然后成立必然进入high--,直到找到一个大于temp的放到左边即下面的else a[low] = a[high];
high--;
if(low == high)
break;
else
a[low] = a[high];
//大于标杆的在左
while(low < high && a[low] >= temp)
low++;
if(low == high)
break;
else
a[high] = a[low];
}
a[low] = temp;
returnlow;
}
intquickSort(vector<int>& a, intlow, inthigh, intK){
//先进行一轮划分,p下标左边的都比它大,下标右边都比它小
intp = partion(a, low, high);
//这是如何继续划分
//若p刚好是第K个点,则找到
if(K == p - low + 1)
returna[p];
//从头到p超过k个数组,则目标在左边
elseif(p - low + 1> K)
//递归左边
returnquickSort(a, low, p - 1, K);
else
//否则,在右边,递归右边,但是需要减去左边更大的数字的数量
returnquickSort(a, p + 1, high, K - (p - low + 1));
}
intfindKth(vector<int> a, intn, intK) {
returnquickSort(a, 0, n - 1, K);
}
};