子集和问题

子集和问题的一个实例为〈S,t〉。其中,S={ x1, x2,…, xn}是一个正整数的集合,c是一个正整数。子集和问题

判定是否存在S的一个子集S1,使得子集S1和等于c。 设计一个回溯法来求解该问题。

解题思路:对于该集合的每一个子集,若元素和为正整数c,则将该子集放入解集中,最后返回解集即可。

	/**
	 * @param list 存放所有满足要求的解
	 * @param tempList 存放每一轮的解
	 * @param nums 正整数集合
	 * @param target 目标和
	 * @param start 开始位置
	 * @param sum 每一个子集和
	 */
	public void backtrack(List<List<Integer>> list, ArrayList<Integer> tempList,
			int[] nums, int target, int start, int sum) 
	{
		if (sum == target) 		// 找到一个满足条件的解
		{
			list.add(new ArrayList<>(tempList));
		}
		
		for (int i=start; i<nums.length; i++)
		{
			tempList.add(nums[i]);
			sum += nums[i];
			backtrack(list, tempList, nums, target, i+1, sum);
//			backtrack(list, tempList, nums, target, i+1, sum+nums[i]); 错误代码
			sum -= tempList.get(tempList.size()-1); 
			tempList.remove(tempList.size()-1);
		}
	}
	
	public void subSetSum(int[] s, int target)
	{
		List<List<Integer>> list = new ArrayList<>();
		ArrayList<Integer> tempList = new ArrayList<>();
		backtrack(list, tempList, s, target, 0, 0);
		
		if (list.size() == 0)
			System.out.println("No Solution");
		else
			System.out.println(Arrays.toString(list.toArray()));
	}

也可以省去backtrack函数中的参数sum。代码如下:

	public void backtrack(List<List<Integer>> list, ArrayList<Integer> tempList,
			int[] nums, int target, int start) 
	{
		if (target == 0) 		// 找到一个满足条件的解
		{
			list.add(new ArrayList<>(tempList));
		}
		
		for (int i=start; i<nums.length; i++)
		{
			tempList.add(nums[i]);
			target -= nums[i];
			backtrack(list, tempList, nums, target, i+1);
			target += tempList.get(tempList.size()-1); 
			tempList.remove(tempList.size()-1);
		}
	}

非递归回溯法:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值