Combination Sum I,II,III

本文详细解析了三种组合求和算法:无限次选取候选数组内元素达到目标值、仅限一次选取候选数组内元素达到目标值及从1到9中选取特定数量的数字组合达到目标值。每种算法均采用回溯法实现,并通过示例说明如何避免结果重复。

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

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

For example, given candidate set [2, 3, 6, 7] and target 7

A solution set is: 

[
  [7],
  [2, 2, 3]
]

用回溯法,绕的我好晕,先把别人的答案贴一下,到时候自己在研究下吧,好讨厌递归,,,,

public class Solution {
    List<List<Integer>> res = new ArrayList<List<Integer>>();
	 int[] cans = {}; 
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        cans = candidates;
	   Arrays.sort(cans);
	   backTracking(new ArrayList<Integer>(), 0, target);
	   return res;
    }
    public void backTracking(List<Integer> cur,int from,int target) {
		 
		if (target == 0) {
			List<Integer> list = new ArrayList<Integer>(cur);
			res.add(list);
		}else {
			for (int i = from; i < cans.length && cans[i] <= target; i++) {
				cur.add(cans[i]);
				backTracking(cur, i, target - cans[i]);
				cur.remove(new Integer(cans[i]));
			}
		}
	}
}

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8
A solution set is: 

[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

和1方法相似,但是不允许出现重复结果,每个元素只参与一次运算

public class Solution {
     List<List<Integer>> res = new ArrayList<List<Integer>>();  
    int[] cans = {};  
      
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {  
        this.cans = candidates;  
        Arrays.sort(cans);  
        backTracking(new ArrayList<Integer>(), 0, target);  
        return res;  
    }  
      
    public void backTracking(List<Integer> cur, int from, int target) {  
        if (target == 0) {  
            //查看该解是否已经在结果集中,如对于输入[1,1]和1,只需放一个[1]到结果集中
			boolean exist = false;
			for (int i = res.size() - 1; i >= 0; i--) {
				List<Integer> temp = res.get(i);
				if (temp.size() != cur.size()) {
					continue;
				}
				int j = 0;
				while (j < cur.size() && temp.get(j) == cur.get(j)) {
					j++;
				}
				if (j == cur.size()) {
					exist = true;
					break;
				}
			}
			 //如果当前解不在结果集中,把其加入到结果集中
			if (!exist) {
				List<Integer> list = new ArrayList<Integer>(cur);
				res.add(list);
			}
			return;
		}
		
			for (int i = from; i < cans.length && cans[i] <= target; i++) {
				cur.add(cans[i]);
				backTracking(cur, i+1, target-cans[i]);
				cur.remove(new Integer(cans[i]));
			}
		
    } 
}

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.


Example 1:

Input: k = 3, n = 7

Output:

[[1,2,4]]


Example 2:

Input: k = 3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]

题意就是,给定一个数组,由1到9组成。然后数组中的k个数的和相加等于target。

返回结果集,结果集中的每个结果里面元素的个数都是k个。

和上面问题1,2思路都是一样的,而且问题3中每个元素只能用一次,结果集中也不允许出现重复结果。

public class Solution {
    List<List<Integer>> res = new ArrayList<List<Integer>>();
	int[] nums = {1,2,3,4,5,6,7,8,9};
    public List<List<Integer>> combinationSum3(int k, int n) {
        backTracing(new ArrayList<Integer>(), 0, k,n);
		return res;
    }
    public void backTracing(List<Integer> cur, int from, int k,int target) {
		if (cur.size() <= k) {
			if (target == 0 && cur.size() == k) {
				List<Integer> list = new ArrayList<Integer>(cur);
				res.add(list);
			}else {
				for (int i = from; i < nums.length && nums[i] <= target; i++) {
					cur.add(nums[i]);
					backTracing(cur, i+1, k, target - nums[i]);
					cur.remove(new Integer(nums[i]));
				}
			}
		}
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值