zoukankan      html  css  js  c++  java
  • leetcode之组合数(Combination Sum)

    Combination Sum

    //代码1
    public class Solution {
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            List<List<Integer>> result = new ArrayList<List<Integer>>();
            if(candidates.length == 0 || candidates == null) return result;
            Arrays.sort(candidates);
            List<Integer> list = new ArrayList<Integer>();
            helper(result, list, candidates, 0, target);
            return result;
        }
    
        private void helper(List<List<Integer>> result,
                            List<Integer> list,
                            int[] candidates,
                            int sum,
                            int target) {
            if(sum == target) {
                result.add(new ArrayList<Integer>(list));
                return;
            }
    
            for(int i = 0; i < candidates.length; i++) {//每层的循环都是从0开始,导致出现重复的组合
                if(sum + candidates[i] <= target) {
                    list.add(candidates[i]);
                    helper(result, list, candidates, sum + candidates[i], target);
                    list.remove(list.size() - 1);
                }
                else
                    break;
            }
        }
    }

    Your answer:[[2,2,3],[2,3,2],[3,2,2],[7]]
    Expected answer:[[2,2,3],[7]]

    //代码2
    public class Solution {
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            List<List<Integer>> result = new ArrayList<List<Integer>>();
            if(candidates.length == 0 || candidates == null) return result;
            Arrays.sort(candidates);
            List<Integer> list = new ArrayList<Integer>();
            helper(result, list, candidates, target, 0);
            return result;
        }
    
        private void helper(List<List<Integer>> result,
                            List<Integer> list,
                            int[] candidates,
                            int target,
                            int k) {
            if(target == 0) {
                result.add(new ArrayList<Integer>(list));
                return;
            }
            if(target > 0) {
                for(int i = k; i < candidates.length; i++) {
                    if(target < candidates[i]) break;
                    list.add(candidates[i]);
                    helper(result, list, candidates, target - candidates[i], i);//两处修改的地方
                    list.remove(list.size() - 1);
                }
            }
        }
    }

    正解代码2对代码1做了2点优化:

    1. 每层循环从当前开始层数开始,防止出现重复组合;
    2. 传入的参数由和改为差值,这样可防止在数值很大的情况下出现溢出的异常。

    Combination Sum II

    在回溯法中,如果要去除重复的元素,只需在for循环中加入一个条件判断即可,这个条件判断隐含了两层意思:
    1. 每一层的第一个元素无条件加入解空间树
    2. 这一层从第二个元素开始进行比较,若这个元素与前面元素相同,不应该加入解空间树

    public class Solution {
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            List<List<Integer>> result = new ArrayList<List<Integer>>();
            if(candidates.length == 0 || candidates == null) return result;
            Arrays.sort(candidates);
            List<Integer> list = new ArrayList<Integer>();
            helper(result, list, candidates, target, 0);
            return result;
        }
    
        private void helper(List<List<Integer>> result,
                            List<Integer> list,
                            int[] candidates,
                            int target,
                            int k) {
            if(target == 0) {
                result.add(new ArrayList<Integer>(list));
                return;
            }
            if(target > 0) {
                for(int i = k; i < candidates.length; i++) {
                    if(target < candidates[i]) break;
                    if(i > k && candidates[i] == candidates[i - 1]) continue;//多个一个判断条件
                    list.add(candidates[i]);
                    helper(result, list, candidates, target - candidates[i], i + 1);//在代码2中,这里是i
                    list.remove(list.size() - 1);
                }
            }
        }
    }
  • 相关阅读:
    【WPF】【基础】布局系统
    【设计】【托管扩展性框架】 MEF vs 2010 samples
    【wpf】【控件】内容控件
    【Wpf】【debug】Exception has been thrown by the target of an invocation.
    【设计模式】概述
    期待与悲催中的2012
    金额转为大写人民币
    使用vs2005的GridView控件,菜鸟问题。
    Microsoft Visual Studio 2005中使用水晶报表
    将金额小写转化成汉字大写(javascript)
  • 原文地址:https://www.cnblogs.com/season-peng/p/6713497.html
Copyright © 2011-2022 走看看