215. 数组中的第K个最大元素(中等)

本文介绍了一种基于快速排序思想的算法,用于查找数组中第K大的元素。该算法采用分治策略,通过一次遍历实现平均O(N)的时间复杂度,并保持O(1)的空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值