无序数组求第K大

对于第k大,我们可以用堆排序求前k大,还可以用快速排序的思想,求出第k大,我们会发现,当求出的下角标等于我们想要的k时,就是第k大元素了.

import java.util.Scanner;


public class demo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int[] a = {1,4,7,8,9};
		int ans = solve(a,2);
		System.out.println("ans: "+ans);
	}

	private static int solve(int[] a, int k) {
		int l = 0;
		int r = a.length - 1;
		int index = 0;
		while(index!=k){
			index = qucik_sort(a,l,r);
			if(index<k){
				l = index + 1; 
			}else if(index>k){
				r = index - 1;
			}
		}
		return a[index];
	}

	private static int qucik_sort(int[] a, int l, int r) {
		if(l<r){
			int i = l;
			int j = r;
			int temp = a[i];
			while(i<j){
				while(i<j&&a[j]>=temp){
					j--;
				}
				a[i] = a[j];
				while(i<j&&a[i]<=temp){
					i++;
				}
				a[j] = a[i];
			}
			a[i] = temp;
			return i;
		}
		return -1;
	}

}


### 解决方案 为了在无序数组中高效地找到第K的数,可以采用基于快速选择算法的方法。该方法源自快速排序的思想,在平均情况下具有线性时间复杂度O(n)[^1]。 #### 基本概念 快速选择是一种用于在线性时间内解决问题的选择算法。它通过分区操作来减少处理的数据规模,直到定位到所需的元素位置为止。具体来说: - **分区函数**:选定一个枢轴(pivot),通常可以选择第一个元素、最后一个元素或是随机选取; - **分割过程**:将所有小于等于枢轴的元素移动至其左侧,其余放置在其右侧; - **递归调用**:依据当前枢轴的位置决定下一步是在左半区还是右半区间继续执行相同的操作; 当目标索引正好对应于某个特定分界点时,则找到了所的第K数值[^3]。 #### Python 实现代码 下面给出了一段Python版本的具体实现方式: ```python import random def find_kth_largest(nums, k): """返回列表 nums 中第 k 数字""" def partition(left, right, pivot_index): pivot_value = nums[pivot_index] # 将枢轴移到末尾 nums[pivot_index], nums[right] = nums[right], nums[pivot_index] store_index = left # 移动较小项到左边 for i in range(left, right): if nums[i] > pivot_value: # 寻找第k而非第k小因此这里使用> nums[store_index], nums[i] = nums[i], nums[store_index] store_index += 1 # 放回枢轴 nums[right], nums[store_index] = nums[store_index], nums[right] return store_index def select(left, right, k_smallest): """ 返回列表 nums 的子集 [left:right+1] 中第 k_smallest 小的数字, 即整个列表中的第 (len(nums)-k) 数字。 """ if left == right: return nums[left] # 随机化枢轴以提高性能稳定性 pivot_index = random.randint(left, right) pivot_index = partition(left, right, pivot_index) if k_smallest == pivot_index: return nums[k_smallest] elif k_smallest < pivot_index: return select(left, pivot_index - 1, k_smallest) else: return select(pivot_index + 1, right, k_smallest) n = len(nums) return select(0, n - 1, n - k) # 测试案例 print(find_kth_largest([3, 2, 1, 5, 6, 4], 2)) # 输出应为5 ``` 此代码实现了上述提到的核心逻辑,并且加入了随机化的策略来增强实际应用中的表现效果。需要注意的是,这里的`find_kth_largest()`函数接收两个参数——待查询的整型列表以及表示所需排名小的一个正整数k。最终输出的结果即为目标值所在处的内容。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值