随机选择实现

随机选择实现:

可能经常会提到在数组中找第几小或第几大的问题,这里主要以随机选择(找第i小)来实现,其主要思想还是借助快速排序(http://my.oschina.net/indestiny/blog/203927)当中的划分思想来解决,只不过不用对划分后的两个子数组都做处理,只需处理其中一个,思想比较简洁,实现代码如下:

/**
 * 找出数组种从下标p到r之间第i小的数
 * @param arr 目标数组
 * @param p 数组起始索引
 * @param r 数组结束索引
 * @param i 第i小?
 * @return 第i小的数值
 */
private static int randomSelect(int[] arr, int p, int r, int i) {
	if (p == r) return arr[p];
	int q = randomPartition(arr, p, r);
	int k = q - p + 1;
	if (i == k){ 
		return arr[q];
	} else if(i < k){ //第i大在左边数组
		return randomSelect(arr, p, q-1, i);
	} else{ //第i大在右边数组
		return randomSelect(arr, q+1, r, i-k);
	}
}

/**
 * 对数组进行随机划分 
 * @param arr 待划分数组
 * @param p 数组起始索引
 * @param r 数组结束索引
 * @return 最终基准所在的索引值
 */
private static int randomPartition(int[] arr, int p, int r) {
	//[p..r]间产生一个随机索引
	int index = Math.random(p, r); 
	ArrayUtil.swap(arr, index, r);
	return partition(arr, p, r);
}
	
/**
 * 对数组进行划分
 * @param arr 待划分数组
 * @param p 数组起始索引
 * @param r 数值结束索引
 * @return 基准数的索引
 */
private static int partition(int[] arr, int p, int r) {
	int pivot = arr[r];
	int i = p-1;
	for (int j=p; j<=r-1; j++){
		if (arr[j] < pivot){
			i++;
			ArrayUtil.swap(arr, i, j);
		}
	}
	ArrayUtil.swap(arr, i+1, r);
	return i+1;
}
测试用例:
int[] arr = new int[]{12, 32,11, 5,13,4};
int target = 2;
int res = randomSelect(arr, 0, arr.length-1, target);
System.out.println("第"+target +"小的是: " + res);

转载于:https://my.oschina.net/indestiny/blog/205572

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值