LeetCode第40题:组合总和2(中等)

LeetCode第40题:组合总和2(中等)

  • 题目:给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次。
  • 解法一:想用减法的方式,但是一旦满足条件就退出了(例如{1,2,6}结束后{1,7}就找不到了)
class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> ans=new ArrayList<>();
        int len=candidates.length;
        if(len==0) return ans;
        Arrays.sort(candidates);
        for(int i=0;i<len;i++){
            List<Integer> ans2=new ArrayList<>();
            int j=i;
            int t=target;
            if(candidates[i]<=target)
            while(j<len && candidates[j]<=target){
                if(t-candidates[j]==0){
                    ans2.add(candidates[j]);
                    ans.add(ans2);
                    break;
                }else if(t-candidates[j]>0){
                    t=t-candidates[j];
                    ans2.add(candidates[j]);
                    j++;
                }else{
                    t=t+candidates[j-1];
                    int len2=ans2.size();
                    ans2.remove(len2-1);

                }
            }
        }
        return ans;
    }
}
  • 解法二:昨天那道题的思想,运用了递归方法,只能说是看懂了。。。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class Solution {


    // residue 表示剩余,这个值一开始等于 target,基于题目中说明的"所有数字(包括目标数)都是正整数"这个条件
    // residue 在递归遍历中,只会越来越小
    private void findCombinationSum2(int[] candidates, int begin, int len, int residue, Stack<Integer> stack, List<List<Integer>> res) {
        if (residue == 0) {
            res.add(new ArrayList<>(stack));
            return;
        }
        for (int i = begin; i < len && residue - candidates[i] >= 0; i++) {
            // 这一步之所以能够生效,其前提是数组一定是排好序的,这样才能保证:
            // 在递归调用的统一深度(层)中,一个元素只使用一次。
            // 这一步剪枝操作基于 candidates 数组是排序数组的前提下
            if (i > begin && candidates[i] == candidates[i - 1]) {
                continue;
            }
            stack.add(candidates[i]);
            // 【关键】因为元素不可以重复使用,这里递归传递下去的是 i + 1 而不是 i
            findCombinationSum2(candidates, i + 1, len, residue - candidates[i], stack, res);
            stack.pop();
        }
    }

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        int len = candidates.length;
        List<List<Integer>> res = new ArrayList<>();
        if (len == 0) {
            return res;
        }
        // 先将数组排序,这一步很关键
        Arrays.sort(candidates);
        findCombinationSum2(candidates, 0, len, target, new Stack<>(), res);
        return res;
    }

    public static void main(String[] args) {
        int[] candidates = {10, 1, 2, 7, 6, 1, 5};
        int target = 8;
        Solution solution = new Solution();
        List<List<Integer>> combinationSum2 = solution.combinationSum2(candidates, target);
        System.out.println(combinationSum2);
    }
}

作者:liweiwei1419
链接:https://leetcode-cn.com/problems/combination-sum-ii/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
发布了79 篇原创文章 · 获赞 7 · 访问量 1400

猜你喜欢

转载自blog.csdn.net/new_whiter/article/details/103616633
今日推荐