思路:
1.暴力快排Arrays.sort()
2.分治(快速排序)
代码:
class Solution {
public int findKthLargest(int[] nums, int k) {
int target=nums.length-k;
int index=partition(nums,0,nums.length-1,target);
return nums[index];
}
private int partition(int[] nums,int left,int right,int target){
int x=nums[left];
//j设置与选定点一致的下标
int j=left;
//遍历完之后,nums[left+1,j]<x nums(j,i]>x
for(int i=left;i<=right;i++){
if(nums[i]<x){
j++;
swap(nums,i,j);
}
}
//nums[j]比nums[left]小
//nums[j+1]比nums[left]大
//则换一下left和j即可
swap(nums,left,j);
if(target==j) return j;
else if(j<target){
return partition(nums,j+1,right,target);
}else{
return partition(nums,left,j-1,target);
}
}
private void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
分解:
1)快速排序:(只是利用了快排的思想,不是典型的快排)
第一遍排序完后,j之前包括j的所有的元素都比left的元素要小
此时再交换一次,nums[j]和nums[left]交换,则left之前的所有值都比当前nums[left]要小
swap(nums,left,j)
for(int i=left;i<=right;i++){
if(nums[i]<x){
j++;
swap(nums,i,j);
}
}
2)下面进行分治:
if(target==j) return j;
else if(j<target){
return partition(nums,j+1,right,target);
}else{
return partition(nums,left,j-1,target);
}
复杂度分析:
时间复杂度:O(N)
首先不是一个完全的递归树,按照每次排序刚好定位到中间来想,递归树的下一层只有T(n/2),不考虑另一半;其次,每一层递归树都要遍历对应的, "分而治之"的”分“后的数组长度,所以+n 这样来算用Master method,T(n) = aT(n/b) + f(n), f(n) = n,a=1,b=2, f(n) = Ω(n的 (以b为底a的对数 + x) 次方 ),x>0, 所以T(n) = O(f(n))=O(n)
空间复杂度:O(1)