首页 > 试题广场 >

组合之和

[编程题]组合之和
  • 热度指数:9890 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给出一组候选数C和一个目标数T,找出候选数中加起来和等于T的所有组合。
C中的数字在组合中可以被无限次使用
注意:
  • 题目中所有的数字(包括目标数T)都是正整数
  • 你给出的组合中的数字 (a 1, a 2, … , a k) 要按非递减排序 (ie, a 1 ≤ a 2 ≤ … ≤ a k).
  • 结解集中不能包含重复的组合
例如:给定的候选数集是[20,30,60,70],目标数是7
解集是:
[70]
[20, 20, 30]
import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
		Arrays.sort(candidates);
		dfs(candidates,target,0,new ArrayDeque<>(),res);
		return res;
    }
    private void dfs(int[] candidates, int residue, int begin, Deque<Integer> path, ArrayList<ArrayList<Integer>> res) {
		if (residue == 0) {
			res.add(new ArrayList<>(path));
		}
		for (int i = begin; i < candidates.length; i++) {
			if (residue - candidates[i] < 0) {
				break;
			}
			path.addLast(candidates[i]);
			dfs(candidates, residue - candidates[i], i, path, res);
			path.removeLast();
		}
	}
}

发表于 2020-08-01 16:30:04 回复(0)
import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
    public ArrayList<ArrayList<Integer>> combinationSum(int[] num, int target) {
        if(num == null || num.length == 0 || target <= 0)
            return res;
        Arrays.sort(num);
        ArrayList<Integer> list = new ArrayList<Integer>();
        Solve(num, list,0, target, 0);
        return res;
    }
    public void Solve(int[] num, ArrayList<Integer> list, int start, int target, int sum){
        if(sum == target){
            res.add(new ArrayList<Integer>(list));
            return;
        }
        if(sum > target){
            return;
        }
        for(int i = start; i < num.length; i++){
            if(sum < target){
                list.add(num[i]);
                sum += num[i];
                Solve(num, list,i,target, sum);
                list.remove(list.size() - 1);
                sum -= num[i];
            }
        }
        return;
    }
}

发表于 2019-09-07 18:20:52 回复(0)
import java.util.*;

public class Solution {

    /**
     * 在C中找[所有加起来等于T]的集合
     * 1.C中的元素可以重复使用
     * 2.所有数为正
     * 3.非递减排序
     * 
     * 思路:分解问题。对于C中的某一个元素来说,当使用了这个元素时,
     * combinationSum(candidates,target,idx) -> combinationSum(candidates,target-candidates[i],i)
     * 
     * 测试用例设计:
     * 7 4 2 1    11
     * 2 4 3 8    1
     * 3 7 11 13  11
     */
    public ArrayList<ArrayList<Integer>> combinationSum(int[] candidates, int target) {
        //题目没有有序,所以排序
        Arrays.sort(candidates);
        ArrayList<ArrayList<Integer>> res = combinationSumCore(candidates, target, 0);
        return res != null ? res : new ArrayList<>();
    }

    private ArrayList<ArrayList<Integer>> combinationSumCore(int[] candidates, int target, int idx) {
        if (idx >= candidates.length) return null;
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        for (int i = idx; i < candidates.length; i++) {
            //当前target小于当前元素
            if (target < candidates[i]) break;
            //当前target等于当前元素
            else if (candidates[i] == target) {
                ArrayList<Integer> t = new ArrayList<>();
                t.add(candidates[i]);
                res.add(t);
            } else {
                //当前target大于当前元素
                ArrayList<ArrayList<Integer>> temp = combinationSumCore(candidates, target - candidates[i], i);
                if (temp != null) {
                    for (int j = 0; j < temp.size(); j++) {
                        ArrayList<Integer> t = temp.get(j);
                        t.add(0, candidates[i]);
                        res.add(t);
                    }
                }
            }
        }
        return res.size() != 0 ? res : null;
    }
}
编辑于 2019-05-24 13:06:41 回复(0)

Combination Sum : https://leetcode.com/problems/combination-sum/

public List<List<Integer>> combinationSum(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>();
    Arrays.sort(nums);
    backtrack(list, new ArrayList<>(), nums, target, 0); return list;
} private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){
            tempList.add(nums[i]);
            backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements tempList.remove(tempList.size() - 1);
        }
    }
}
发表于 2017-03-12 14:53:04 回复(0)

问题信息

难度:
5条回答 23154浏览

热门推荐

通过挑战的用户

查看代码