题目描述
思路
1.排序直接输出k个数 时间复杂度O(nlogn) 空间复杂度O(logn)
2.利用hash表,进行查表 时间复杂度O(n) 空间复杂度O(n)
3.利用快排序划分,第一次划分为i,判断i>k或者<k然后大于k在左边进行划分,小于k在右边继续划分。时间复杂度:期望为 O(n) 空间复杂度 期望为 O(log n)O(logn)
代码
法一
sort(arr.begin(),arr.end());
vector<int> ret(arr.begin(),arr.begin()+k);
return ret;
法二
vector<int> getLeastNumbers(vector<int>& arr, int k) {
//创建表存储
map <int,int> has;
for(int i=0;i<arr.size();i++)
{
has[arr[i]]++;
}
vector<int> ret;
for(int i=0;i<=10000;i++)
{
//查表是否含有元素
if(has.count(i))
{
//元素有可能出现两次
while(has[i]--)
if(has[i]>=0)
{
if(k==0)
return ret;
ret.push_back(i);
k--;
}
}
}
return ret;
}
法三
class Solution {
public:
vector<int> res;
vector<int> getLeastNumbers(vector<int>& arr, int k) {
//奇奇怪怪的输入用例
if(arr.size()==0||k==0)
return res;
//查找的个数大于数组长度
if(k>=arr.size())
return arr;
quickSearch(arr,k,0,arr.size()-1);
return res;
}
void quickSearch(vector<int> &arr,int k,int low, int high)
{
int retMid = partition(arr,low,high);
cout<<retMid;
//找到
if(retMid == k)
{
vector<int> ret(arr.begin(),arr.begin()+k);
res = ret;
return;
}
//在左边找
if(retMid>k)
quickSearch(arr,k,low,retMid-1);
//在右边找
if(retMid<k)
quickSearch(arr,k,retMid+1,high);
}
int partition(vector<int>& arr,int low,int high)
{
int pivot = arr[low];
int i = low;
int j = high;
while(i<j)
{
//注意限制条件i<j并且限制条件大于等于pivot
while(arr[j] >= pivot && j>i)
j--;
arr[i] = arr[j];
while(arr[i] <= pivot && i<j)
i++;
arr[j] = arr[i];
}
arr[i] = pivot;
return i;
}
};
重难点分析
坚持创作,互联网行业深度!
1.快排划分对于重复数字的处理,即是判断条件大于等于
2.可优化快排,随机取值作为pivot。
int i = rand() % (r - l + 1) + l; //l 左 r右。 然后swap