问题描述:
解题分析:
这题没什么难度,就是把数组排序,然后取出前k个。
之所以写出来,就是因为我好像很久没写快排了
方法一:使用sort直接排序
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
sort(arr.begin(),arr.end());
vector<int>nums;
if(k==0)
{
return nums;
}
while(k>=1)
{
nums.push_back(arr[k-1]);
k--;
}
return nums;
}
};
方法二:回顾一下快排
快速排序的基本思想: 通过一趟排序将数组分割成2个部分,其中一部分要比基准数小,一部分要比基准数大,再按照这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,是整个数组变成有序序列。
一般取数组最左边的数做基准数。把小于基准数的移到基准数的左边,大于基准数的移到基准数的右边,相等的数不移动。
快速排序的操作:
设最左边下标为
i
i
i,最右边下标为
j
j
j. 首先从数组的右边进行查找,也就是进行
j
−
−
j--
j−−操作,找到了比基准数小的,让基准数与其进行交换。然后从从左边进行查找,也就是进行
i
+
+
i++
i++操作,找到了比基准数大的,让基准数与其进行交换。直到
i
与
j
i与j
i与j相遇结束。
过程如图所示:
但是我研究了下评论,发现了一个简单的写法,就是每次交换可以不用交换基准数的位置
而是把扫描到的不合适的
i
和
j
i和j
i和j进行交换
遍历了一遍后
把基准数和num[i]交换。
然后在左边右边进行递归.
如代码所示:
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
//快排
quickSort(arr,0,arr.size()-1);
vector<int>nums;
if(k==0)
{
return nums;
}
while(k>=1)
{
nums.push_back(arr[k-1]);
k--;
}
return nums;
}
private:
void quickSort(vector<int>& arr,int left,int right)
{
if(left>=right) return;
//取最左边为基准数
int i=left,j=right;
while(i<j)
{
while(i<j && arr[j]>=arr[left]) j--; //如果右边的数字 小于基准数,就进行交换;否则,就继续往前走
while(i<j && arr[i]<=arr[left]) i++;//如果左边的数字 大于基准数,就进行交换;否则,就继续往后走
swap(arr[i],arr[j]);
}
swap(arr[i],arr[left]); //把基准数放在中间
//划分左右区间
quickSort(arr,left,i-1);
quickSort(arr,i+1,right);
}
};