分治法--选择问题

对于给定的包含n个元素的数组,要求从中找出第k小的元素

输入:第一行是整数n和k,第二行是n个整数

输出:第k小的元素

输入样例:

7 3

4 59 7 23 61 55 46

输出样例:23

思路:结合快速排序算法,排序后分界值左边有n个元素,

(1).n=k-1,则分界值即为结果

(2).n<k-1 则继续在右子集中查找,k变为k-(i-left+1)(减去包括分界值和左子集的元素个数)

(3).n>k-1 继续在左子集中查找

代码:

package 测试;
import java.io.*;
import java.util.Scanner;
public class 快速排序求数组中第n小的元素 {
static int[]aim;
static int n,k;
static int f(int left,int right,int k){
	int i = left,j = right;
	int b = aim[left];
	while(i<j){
		//从右侧扫描
		while(i<j && aim[j]>=aim[i]) j--;
		if(i<j){
			int e = aim[i];
			aim[i] = aim[j];
			aim[j] = e;
		}
		//从左侧扫描
		while(i<j && aim[i]<=aim[j])i++;
		if(i<j){
			int ee = aim[j];
			aim[j] = aim[i];
			aim[i] = ee;
		}
	}
	if(i+1-left == k)return b;
	else if(i+1>k) return f(left,i-1,k);
	else return f(i+1,right,k-i+left-1);
}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		k = sc.nextInt();
		aim = new int[n];
		for(int i=0;i<aim.length;i++)
			aim[i] = sc.nextInt();
		System.out.println(f(0,aim.length-1,k));
			
	}

}

分治法是一种常用的算法设计范式,通过将问题分解成更小的子问题来解决。0-1背包问题是一个经典的组合优化问题,目标是选择一组物品,使得在不超过背包容量的情况下,物品的总价值最大化。分治法可以通过递归地将问题分解成子问题来解决0-1背包问题。 具体步骤如下: 1. **分解问题**:将背包问题分解成两个子问题,一个是包含当前物品的子问题,另一个是不包含当前物品的子问题。 2. **解决子问题**:递归地解决这两个子问题。 3. **合并结果**:选择两个子问题中价值最大的一个作为当前问题的解。 伪代码如下: ```python def knapsack(items, capacity): if not items or capacity == 0: return 0 # 如果当前物品的重量大于背包容量,则不选择当前物品 if items[0].weight > capacity: return knapsack(items[1:], capacity) else: # 选择当前物品和不选择当前物品两种情况的最大值 include = items[0].value + knapsack(items[1:], capacity - items[0].weight) exclude = knapsack(items[1:], capacity) return max(include, exclude) ``` 在这个伪代码中,`items`是一个包含物品的列表,每个物品有重量和价值,`capacity`是背包的容量。函数`knapsack`通过递归地解决子问题来找到最优解。 然而,分治法在解决0-1背包问题时的时间复杂度是指数级的,因此在处理大规模问题时效率较低。为了提高效率,可以使用动态规划来优化算法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值