int findKthLargest(vector<int>& nums, int k) {
//排序 O(nlogn) nums[k]
//能不能有O(n)的算法呢?
int left= 0,right=nums.size()-1; //[left,right]
return partition(nums,left,right,k);
}
int partition(vector<int>& nums,int left,int right,int k){//nums[left,right]
if(left==right){
return nums[left];
}
int pivot=nums[left];
int l=left,r=right;
while(l<r){
while(l<r&&nums[r]<=pivot)//必须要将大于key写在前面 不然会出bug
r--;
while(l<r&&nums[l]>=pivot)
l++;
if(l<r)
swap(nums[l],nums[r]);
}
swap(nums[l],nums[left]);
int curk=l-left+1;
if(curk==k){
return pivot;
}else if(curk>k){
return partition(nums,left,l-1,k);
}else{
return partition(nums,l+1,right,k-curk);
}
}
当时做的时候,出了一个BUG,调试了很久,关于partition的错误(partition的写法有很多种) :
while(l<r){
while(l<r&&nums[r]<=pivot)//必须要将大于key写在前面 不然会出bug
r--;
while(l<r&&nums[l]>=pivot)
l++;
if(l<r)
swap(nums[l],nums[r]);
}
利用swap()函数,必须要将大于pivot写在前面,小于pivot写在后面,因为这样能保证,当退出里面第一个while循环是,当前的j值一定指向小于pivot的数,而里面的第二个while循环可以因为i值等于j值而退出循环,此时i,j都指向小于pivot值得数,最后才能将该值与pivot值交换。
void sortColors(vector<int>& nums) {
//直接排序 O(nlogn)
int k=nums.size();
int left=0,right=k-1; //[0..left) (right,k-1]
for(int i=left;i<=right;){
if(nums[i]==0){
swap(nums[i],nums[left]);
left++;
i++;//这一步我没想到,交换过来的nums[left]的值肯定1,所以要i++;
}else if(nums[i]==2){
swap(nums[i],nums[right]);
right--; //这里不要i++,因为交换过来的nums[right]的值是不确定的。
}else{
i++;
}
}
}
比较简单:通过[0,left)控制0的元素,(right,nums.size()-1]控制数值2的元素,数值1的元素就自然在中间了