代码编织梦想

语言

Java

39. 组合总和  

组合总和

题目

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

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

思路

本题依然采取递归的方法,我先定义了两个全局变量 一个结果二维数组,一个收集数据的一维数组。在主方法里对数组进行排序,然后进行递归,最后返回结果数组。

递归三部曲 递归参数:target、数组candidates、sum、index

递归终止条件:sum等于target 将合格的数组加入到结果数组中

单层递归:for循环控制结果集大小和遍历次数、递归用来收集数据。

代码

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        backtracking(candidates, 0, target, 0);
        return res;
    }
    public void backtracking(int[] candidates, int sum, int target, int index) {
        if (sum == target) {
            res.add(new ArrayList<>(list));
            return;
        }
        for (int i = index; i < candidates.length; i++) {
            if (sum + candidates[i] > target) return;
            sum += candidates[i];
            list.add(candidates[i]);
            backtracking(candidates, sum, target, i);
            sum -= candidates[i];
            list.removeLast();
        }
    }
}

易错点

需要进行剪枝操作,第一步就是数组要排序,第二部在单层递归的时候进行判断,如果sum > target就直接返回。

40.组合总和II

组合总和II

题目

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

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

注意:解集不能包含重复的组合。

思路

本题依然采取递归的方法,我先定义了两个全局变量 一个结果二维数组,一个收集数据的一维数组。在主方法里对数组进行排序,然后进行递归,最后返回结果数组。

递归三部曲 递归参数:target、数组candidates、sum、index

递归终止条件:sum等于target 将合格的数组加入到结果数组中

单层递归:for循环控制结果集大小和遍历次数、递归用来收集数据。并且递归的index参数变为i+1

需要注意的是本题需要去重,不仅要将list结果去重,并且每个元素只能使用一次。

代码

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        backtracking(candidates, target, 0, 0);
        return res;
    }
    public void backtracking(int[] candidates, int target, int sum, int index) {
        if (sum == target) {
            res.add(new ArrayList<>(list));
            return;
        }
        for (int i = index; i < candidates.length; i++) {
            if (sum + candidates[i] > target) return;
            if (i > index && candidates[i] == candidates[i - 1]) continue;
            list.add(candidates[i]);
            sum += candidates[i];
            backtracking(candidates, target, sum, i + 1);
            sum -= candidates[i];
            list.removeLast();
        }
    }
}

易错点

需要对list进行去重

如果没有去重重复的list数组

131.分割回文串

分割回文串

题目

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 

回文串

 。返回 s 所有可能的分割方案。

思路

本题依然采取递归的方法,我先定义了两个全局变量 一个结果二维数组,一个收集字符串的一维数组。在主方法里进行递归,最后返回结果数组。下面递归三部曲。

递归终止条件:分割线大于等于字符串长度,代表切完且判断完了,将字符串数组加到结果数组中。

递归参数:字符串,索引。索引也就代表分割线

单程递归逻辑:判断是否为回文数,如果是就加到字符串数组,不是就继续切割。记得回溯

代码

class Solution {
    List<List<String>> res = new ArrayList<>();
    List<String> list = new LinkedList<>();
    public List<List<String>> partition(String s) {
        backTracking(s, 0);
        return res;
    }
    public void backTracking(String s, int startIndex) {
        if (startIndex >= s.length()) {
            res.add(new ArrayList<>(list));
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            if (isPartition(s, startIndex, i)) {
                String str = s.substring(startIndex, i + 1);
                list.add(str);
            } else {
                continue;
            }
            backTracking(s, i + 1);
            list.removeLast();
        }
    }
    public boolean isPartition(String s, int startIndex, int end) {
        for (int i = startIndex,j = end; i < j; i++,j--) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
        }
        return true;
    }
}

易错点

终止条件为什么是大于字符串长度一开始我没理解,因为他是代表分割线,而且先进行判断的是不是回文数。

还有这道题用List和Deque都可以。

总结

回溯算法的第二天 接触到了切割。明天继续努力!

博观而约取、厚积而薄发。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/q864508127/article/details/140683429

代码随想录day27|39. 组合总和|40.组合总和ii|131.分割回文串|golang_扣1送肥猫的博客-爱代码爱编程

代码随想录day27 目录 代码随想录day27 39、组合总和 40.组合总和II 131、分割回文串 39、组合总和         给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取

代码随想录刷题day27 | 39. 组合总和 | 40. 组合总和 ii | 131. 分割回文串_dum1615的博客-爱代码爱编程

代码随想录刷题Day27 | 39. 组合总和 | 40. 组合总和 II | 131. 分割回文串 39. 组合总和 题目: 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找

代码随想录day27|39. 组合总和40. 组合总和 ii131. 分割回文串-爱代码爱编程

class Solution: def backtracking(self, candidates, target, total, startIndex, path, result): if total > target: return if total == target:

day27|39. 组合总和 40.组合总和ii 131.分割回文串-爱代码爱编程

39. 组合总和 题目链接:https://leetcode.com/problems/combination-sum Given an array of distinct integers candidates

代码随想录算法训练营day27 | 39. 组合总和40.组合总和ii 131.分割回文串-爱代码爱编程

代码随想录算法训练营Day27 | 39. 组合总和40.组合总和II 131.分割回文串 LeetCode 39. 组合总和 题目链接:LeetCode 39. 组合总和 思路: 收集元素,起点为i,而不是i+1

算法训练营第47天|1143.最长公共子序列|1035.不相交的线|53. 最大子序和|392.判断子序列-爱代码爱编程

1143.最长公共子序列 思路:这道题比较难理解的是递推公式,要想明白状态转换和各个状态的意义。 如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1; 如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1

学习记录day18——数据结构 算法-爱代码爱编程

算法的相关概念         程序 = 数据结构 + 算法 算法是程序设计的灵魂,结构式程序设计的肉体 算法:计算机解决问题的方法护额步骤 算法的特性 1、确定性:算法中每一条语句都有确定的含义,不能模棱两可 2、有穷性:程序执行一段时间后会自动结束 3、输入:有零个或多个输入 4、输出:至少一个输出,可输出多个 5、可行性:经济可行性

codeforces round 961 (div. 2)-爱代码爱编程

A题:Diagonals 题意 给定一个n x n的网格,k个筹码,放在某个位置,则其对应的右上-左下对角线被占用,问占用的对角线数量最少是多少? 思路 模拟 每次我们都往格子最多的对角线上放,然后次多... 很容易看出来 代码 inline void solve() { int n, k; cin >> n >

1137. 第 n 个泰波那契数-爱代码爱编程

1137. 第 N 个泰波那契数 题目链接:1137. 第 N 个泰波那契数 代码如下: class Solution { public: int tribonacci(int n) {

day23 | 39. 组合总和 40.组合总和ii 131.分割回文串 leetcode 39. 组合总和-爱代码爱编程

代码随想录算法训练营第23 天| 39. 组合总和 40.组合总和II 131.分割回文串 Leetcode 39. 组合总和 题目链接:https://leetcode.cn/problems/combination-

day.20 | 39.组合总和 40.组合总和ii 131.分割回文串-爱代码爱编程

39.组合总和 要点:元素可以重复,那么遍历的startIndex就跟之前的回溯算法不一样了; class Solution { public: vector<vector<int>> result; vector<int> path; void backtracking(vector<

day23|39. 组合总和,40.组合总和ii ,131.分割回文串-爱代码爱编程

39. 组合总和 39. 组合总和 - 力扣(LeetCode) class Solution { public: vector<vector<int>> ans; vector<int> path; void combinationSum(vector<int>& can