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

39. 组合总和

给你一个 无重复元素的整数数组 candidates和一个目标整数 target,找出 candidates  中可以使数字和为目标数 target的 所有 **不同组合,并以列表形式返回。你可以按 任意顺序  返回这些组合。

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。

回溯三部曲:

  1. 确定参数和返回值:返回值为void,参数为数组candidates,目标和target,记录sum,选取开始的索引startIndex

  2. 终止条件:sum==target将结果添加到relsut中返回

  3. 单层搜索逻辑

    处理节点、递归、回溯

    其中剪枝处理,如果sum + candidates[i] > target就会不符合条件

class Solution {
  List<List<Integer>> reslut=new ArrayList<>();
    List<Integer> res=new ArrayList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates); // 先进行排序
        trackbacking(candidates,target,0,0);
        return reslut;
    }
    public void trackbacking(int[] candidates,int target,int sum,int startIndex){
        if(sum==target){
            reslut.add(new ArrayList<>(res));
            return;
        }
        for(int i=startIndex;i<candidates.length && sum + candidates[i] <= target;i++){
            res.add(candidates[i]);
            trackbacking(candidates,target,sum+candidates[i],i);
            res.remove(res.size()-1);
        }
    }
}

40. 组合总和 II

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

**集合(数组candidates)有重复元素,但还不能有重复的组合,**所以这道题的关键是去重

回溯三部曲:

  1. 参数和返回值:返回值为void,参数为candidates,target,sum,startIndex

  2. 递归终止条件:sum==target

  3. 单层搜索逻辑

    为了进行去重我们定义了一个boolean数组 used,首先将数组填充为false

    这里首先需要考虑去重candidates[i]==candidates[i-1]&&!used[i-1] 跳过本次循环

    处理节点:处理节点是需要将used[i]设置为true表明这个数出现过

    递归

    回溯:回溯需要将used[i]设置为false,在进行下一层处理

class Solution {
    List<List<Integer>> reslut=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    boolean[] used;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        used = new boolean[candidates.length];
        Arrays.fill(used,false);
        Arrays.sort(candidates);
        trackbacking(candidates,target,0,0);
        return reslut;
    }
    public void trackbacking(int[] candidates,int target,int sum,int startIndex){
        if(sum==target){
            reslut.add(new ArrayList<>(path));
            return;
        }
        for(int i=startIndex;i<candidates.length&&sum + candidates[i] <= target;i++){
            if(i>0&&candidates[i]==candidates[i-1]&&!used[i-1]){
                continue;
            }
            used[i]=true;
            sum+=candidates[i];
            path.add(candidates[i]);
            trackbacking(candidates,target,sum,i+1);
            used[i]=false;
            path.remove(path.size()-1);
            sum-=candidates[i];
        }
    }
}

Arrays.fill(arrayname,value) 方法,用于数组填充

131. 分割回文串

给你一个字符串 s,请你将 **s **分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

组合问题:选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中再选取第三个.....。

切割问题:切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中再切割第三段.....。

回溯三部曲:

  1. 参数和返回值:返回值为void,参数为字符串s,strtindex用来记录分割点

  2. 终止条件:如果切割点strtindex>=s.length()

  3. 单层搜索逻辑

    首先需要判断截取字符串是否为回文,如果为回文用substring截取字符串并添加到path当中

    回溯

    递归

判断是否为回文:只需两个指针,一个从起点开始遍历,一个从末尾开始遍历,如果字符不相等则为false,若相等则为true

class Solution {
    List<List<String>> reslut=new ArrayList<>();
    List<String> path=new ArrayList<>();
    public List<List<String>> partition(String s) {
        trackbacking(s,0);
        return reslut;
    }
    public void trackbacking(String s,int starIndex){
        if(starIndex>=s.length()){
            reslut.add(new ArrayList<>(path));
            return;
        }
        for(int i=starIndex;i<s.length();i++){
            if(isPalindrome(s,starIndex,i)){
                String str=s.substring(starIndex,i+1);
                path.add(str);
            }else{
                continue;
            }
            trackbacking(s,i+1);
            path.remove(path.size()-1);
        }

    }

    //判断回文
    private boolean isPalindrome(String s,int startIndex,int endIndex){
        for(int i=startIndex,j=endIndex;i<j;i++,j--){
            if(s.charAt(i)!=s.charAt(j)){
                return false;
            }
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值