美文网首页
2018-08-13 LeetCode回溯算法(组合总和)总结

2018-08-13 LeetCode回溯算法(组合总和)总结

作者: 菜鸡学算法 | 来源:发表于2018-08-13 21:35 被阅读0次
    1. 组合总和
      candidates 中的数字可以无限制重复被选取
    class Solution {
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            List<List<Integer>> res = new LinkedList<List<Integer>>();
            if(candidates.length == 0 || candidates == null || target <= 0) return res;
            // 先将数组排序避免重复搜素
            Arrays.sort(candidates);
            helper(candidates, target, 0, new LinkedList<Integer>(), res);
            return res;
        }
        private void helper(int[] nums, int target, int index, List<Integer> tmp, List<List<Integer>> res) {
            if (target == 0) {
                res.add(new LinkedList<Integer>(tmp));
                return;
            } else {
                // 选取之后的每个数字都是一种可能性
                for (int i = index; i < nums.length; i++) {
                    if (target < nums[i] ){
                        return;
                    }else{//DFS
                        tmp.add(nums[i]);
                        helper(nums, target - nums[i], i, tmp, res);
                        tmp.remove(tmp.size() - 1);
                    }
                }
            }
        }    
    }
    
    1. 组合总和 II
      candidates 中的每个数字在每个组合中只能使用一次(递归调用时i+1)
      解集不能包含重复的组合(每个递归方法内部相等的值只加入一次)
    if (i > index && nums[i] == nums[i - 1]) continue;
    
    class Solution {
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            List<List<Integer>> res = new ArrayList<>();
            if (candidates == null || candidates.length == 0 || target <= 0) {
                return res;
            }
            Arrays.sort(candidates);
            helper(candidates, 0, new ArrayList<Integer>(), target, res);
            return res;
        }
        private void helper(int[] nums, int index, List<Integer> temp, int target,
    List<List<Integer>> res) {
            if (target == 0) {
                res.add(new ArrayList<Integer>(temp));
                return;
            }
            for (int i = index; i < nums.length; i++) {
                if (i > index&& nums[i] == nums[i - 1]) {
                    continue;
                }
                if (target < nums[i]) {
                    return;
                }
                temp.add(nums[i]);
                helper(nums, i + 1, temp, target - nums[i], res);
                temp.remove(temp.size() - 1);
        }
        }
    }
    
    1. 组合总和 III
      找出所有相加之和为 n 的 k 个数的组合,组合中只含有 1 - 9 的正整数
      每种组合中不存在重复的数字(递归调用时i+1)
    class Solution {
        public List<List<Integer>> combinationSum3(int k, int n) {
            List<List<Integer>> res = new LinkedList<List<Integer>>();
            if( n < 1 || k < 1) return res;
            helper(k, n, 1, new ArrayList<Integer>(), res);
            return res;
        }
        private void helper(int k, int n, int index, List<Integer> tmp, List<List<Integer>> res) {
            if(n == 0 && k == 0) {
                res.add(new ArrayList(tmp));
                return;
            } else if(n < 0 || k == 0) return;//k个数相加和小于n||不到k个数和已经大于n
            for(int i = index; i <= 9; i++) {
                tmp.add(i);
                helper(k - 1, n - i, i + 1, tmp, res);
                tmp.remove(tmp.size() - 1);
            }
        }
    }
    

    方法二

    class Solution {
        public List<List<Integer>> combinationSum3(int k, int n) {
            List<List<Integer>> res = new LinkedList<List<Integer>>();
            if( n < 1 || k < 1) return res;
            helper(k, n, 1, new ArrayList<Integer>(), res);
            return res;
        }
        private void helper(int k, int n, int index, List<Integer> temp, List<List<Integer>> res) {
            if (k < temp.size()) {//k个数相加和小于n
                    return;
                }
            if (n == 0 && temp.size() == k) {
                res.add(new ArrayList<Integer>(temp));
                return;
            }
            for (int i = index; i <= 9; i++) {
                if (n < i) {
                    return;
                }
                temp.add(i);
                helper(k, n - i, i + 1, temp, res);
                temp.remove(temp.size() - 1);
          }
        }
    }
    

    相关文章

      网友评论

          本文标题:2018-08-13 LeetCode回溯算法(组合总和)总结

          本文链接:https://www.haomeiwen.com/subject/tskpbftx.html