回溯 (1)
回溯理论分析
之前二叉树中已经提到了一些回溯的概念,回溯的本质就是递归,因此效率很低。
回溯法解决的问题都可以抽象为树形结构,所有回溯法的问题都可以抽象为树形结构!
因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度。
1 | //回溯算法伪代码 |
77. 组合 - 力扣(LeetCode) (leetcode-cn.com)
给定两个整数 n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。
你可以按 任何顺序 返回答案。
1 | class Solution { |
剪枝操作,就是排除一些没有意义的排序,比如上面的n = 4, k = 4的例子,当startindex从2开始取就没有意义。
为了解决这个问题,改变for循环搜索的起止位置
1 | for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) // i为本次搜索的起始位置 |
216. 组合总和 III - 力扣(LeetCode) (leetcode-cn.com)
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
1 | class Solution { |
与上一题思路差不多,就是新增了一个target记录总和
17. 电话号码的字母组合 - 力扣(LeetCode) (leetcode-cn.com)
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
1 | class Solution { |
39. 组合总和 - 力扣(LeetCode) (leetcode-cn.com)
给你一个 无重复元素 的整数数组 candidates
和一个目标整数 target
,找出 candidates
中可以使数字和为目标数 target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的不同组合数少于 150 个。
1 | class Solution { |
40. 组合总和 II - 力扣(LeetCode) (leetcode-cn.com)
给定一个候选人编号的集合 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
注意这道题和之前的题相比最大的区别就是需要去重。比如candidates = [10,1,2,7,6,1,5]
,target = 8
如果按照前面的方法会输出两个[1,2,5]和[1,7]
;
去重的思路就是加入一个bool
型的数组,记录同一树枝上的元素是否使用过。通过used
数组来解决这个问题。
1 | class Solution { |
131. 分割回文串 - 力扣(LeetCode) (leetcode-cn.com)
给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是 回文串 。返回 s
所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
1 | class Solution { |
93. 复原 IP 地址 - 力扣(LeetCode) (leetcode-cn.com)
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。
- 例如:”0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、”192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。
1 | class Solution { |
78. 子集 - 力扣(LeetCode) (leetcode-cn.com)
给你一个整数数组 nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
就是最普通的回溯的思想~
1 | class Solution { |
90. 子集 II - 力扣(LeetCode) (leetcode-cn.com)
给你一个整数数组 nums
,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
和上一题相比增加了去重,同样也是通过新加一个bool型的used数组进行判断,首先将数组按从小到大排序,然后通过判断如果当前元素与上一个元素相同且前一个元素没有用时,跳过本次循环,这样就实现了去重。
1 | class Solution { |
数字 n
代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
这种类似与组合内的排列组合的题本质上都是回溯的思想
1 | class Solution { |