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

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

  • 题目:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。andidates 中的数字可以无限制重复被选取。
  • 解法一:想用除法计算商和余数,然后再用被除数加余数找下一项,可是实现的只是被除数加余数能整除其他数的情况。后来想用递归的方法算,但是懒得改了。。。
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        int a,b;
        int len=candidates.length;
        List<List<Integer>> ans=new ArrayList<>(); 
        if(len==0) return ans;
        Arrays.sort(candidates);
        for(int i=0;i<len && target>=candidates[i];i++){
            a=target/candidates[i];
            b=target%candidates[i];
            List<Integer> ans1=new ArrayList<>();
            if(a==1){
                if(b==0){
                    ans1.add(candidates[i]);
                    ans.add(ans1);
                }
            }else{
                int c=b;
                while(a>=1){
                    List<Integer> ans2=new ArrayList<>();
                    for(int j=0;j<len && c>=candidates[j];j++){
                        if(c==candidates[j]){
                            for(int k=0;k<a;k++){
                                ans2.add(candidates[i]);
                            }
                            ans2.add(candidates[j]);
                            ans.add(ans2);
                        }
                    }
                    c=c+candidates[i];
                    a--;
                } 
            }
        }
        return ans;
    }
}
  • 解法二:该方法是用了递归和减法,减法解决了我用除法带来的问题
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class Solution {

    private List<List<Integer>> res = new ArrayList<>();
    private int[] candidates;
    private int len;

    private void findCombinationSum(int residue, int start, Stack<Integer> pre) {
        if (residue == 0) {
            // Java 中可变对象是引用传递,因此需要将当前 path 里的值拷贝出来
            res.add(new ArrayList<>(pre));
            return;
        }
        // 优化添加的代码2:在循环的时候做判断,尽量避免系统栈的深度
        // residue - candidates[i] 表示下一轮的剩余,如果下一轮的剩余都小于 0 ,就没有必要进行后面的循环了
        // 这一点基于原始数组是排序数组的前提,因为如果计算后面的剩余,只会越来越小
        for (int i = start; i < len && residue - candidates[i] >= 0; i++) {
            pre.add(candidates[i]);
            // 【关键】因为元素可以重复使用,这里递归传递下去的是 i 而不是 i + 1
            findCombinationSum(residue - candidates[i], i, pre);
            pre.pop();
        }
    }

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        int len = candidates.length;
        if (len == 0) {
            return res;
        }
        // 优化添加的代码1:先对数组排序,可以提前终止判断
        Arrays.sort(candidates);
        this.len = len;
        this.candidates = candidates;
        findCombinationSum(target, 0, new Stack<>());
        return res;
    }

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

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

猜你喜欢

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