代码随想录训练营第二十五天|39. 组合总和 40.组合总和II 131.分割回文串

39组合总和

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class day25_39_组合总和 {
    List<List<Integer>> res=new ArrayList<>();
    List<Integer> path=new LinkedList<>();
    public static void main(String[] args) {
        
    }
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        huisu(candidates,  target, candidates.length);
        return res;

    }
    void huisu(int[] cand,int target,int n){
        //这一题每一个数可以无限次的 用
        //所以终止条件就是sum等于所求
        int sum=0;
        for(int i=0;i<path.size();i++){
            sum+=path.get(i);
        }
        if (sum==target) {
            res.add(new ArrayList<>(path));
            return;
            
        }
        for(int i=0;i<n;i++){
            if (sum+cand[i]>target) {
                break;
                
            }
            path.add(cand[i]);
            //这里是把他加上
            
            huisu(cand, target, n);
            path.remove(path.size()-1);


        }
    }

    
}

这是自己写的第一版本代码,有一个错误,就是

这里的递归的循环初试不应该还是从0 开始,这样就会出现重复的值

应该从i接着开始,也就是可以重复用当前值,但是不会用前面的也就是不会重复

这才是正确的

还有一个点就是要先排序,这个是必要的,不然可能会漏掉答案

组合总和2

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class day25_40_组合总和二 {
    public static void main(String[] args) {
        
    }
    List<List<Integer>> res=new ArrayList<>();
    List<Integer> path=new LinkedList<>();
    boolean[] demo;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
         Arrays.sort(candidates);
         demo=new boolean[candidates.length];
        huisu(candidates,  target, candidates.length,0);
        return res;

    }
    void huisu(int[] cand,int target,int n,int index){
        //这一题每一个数可以无限次的 用
        //所以终止条件就是sum等于所求
        int sum=0;
        for(int i=0;i<path.size();i++){
            sum+=path.get(i);
        }
        if (sum==target) {
            res.add(new ArrayList<>(path));
            return;
            
        }
        for(int i=index;i<n;i++){
            if (sum+cand[i]>target) {
                break;
                
            }
            if(i>0&&cand[i]==cand[i-1]&&demo[i-1]==false){
                continue;
                
            }
            path.add(cand[i]);
            //这里是把他加上
            demo[i]=true;
            
            huisu(cand, target, n,i+1);
            path.remove(path.size()-1);
            demo[i]=false;


        }
    }

    
}

这个和上一题主要是两个不同,一个就是index要是i+1不能是i还有一个就是要去重,这里借用了一个数组进行状态标记非常巧妙,可以有效防止同一层前后元素重复,但是不影响下一层使用相同的元素,非常巧妙

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值