回溯算法
回溯法:实现某个元素选或不选的问题。
回溯法的基本思想
- 选当前元素,递归的进行后续元素的选择;
- 将当前元素拿出,再进行一次不放入该元素,递归的进行后续元素的选择。
- 本来选择放入,再选择不放入的过程,称为回溯试探法。
- 回溯就是,返回之前的状态,再进行一次递归。
- 回溯问题的求解一般流程:
1 | List<List<Object>> res = new ArrayList(); |
回溯法的相关例题
leetcode 78. 求子集 Subsets
1 | Given a set of distinct integers, nums, return all possible subsets. |
1 | List<List<Integer>> result = new ArrayList(); |
leetcode 90. 带有重复元素求子集 Subsets II
1 | Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set). |
- 将数组先进行排序,然后将得到的结果放入set中去重。
- 一定要先排序,否则就会出现
[1,2,2,1]
和[1,1,2,2]
,就会出错。
1 | Set<List<Integer>> result = new HashSet(); |
- 也可以不用set,回溯时遇到相同元素就跳过。
1 | List<List<Integer>> result = new ArrayList(); |
leetcode 46. 全排列 Permutations
1 | Given a collection of distinct integers, return all possible permutations. |
1 | List<List<Integer>> result = new ArrayList(); |
leetcode 47. 有重复元素的全排列 Permutations II
1 | Given a collection of numbers that might contain duplicates, return all possible unique permutations. |
1 | List<List<Integer>> result = new ArrayList(); |
leetcode 39. 和为target的所有组合,选择的元素可重复 Combination Sum
1 | Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. |
- 因为元素可以重复使用,所以backtracking时从
i
开始即可。 - 而且原始数组中无重复元素,所以直接用list即可,否则使用set.
- 类似题目1:leetcode 40. Combination Sum II : 元素不可重复使用:backtracking时从
i+1
开始;原始数组有重复元素:使用set即可。 - 类似题目2:leetcode 216. Combination Sum III:直接初始化原始数组为0-9、判断条件多加一条即可。
1 | List<List<Integer>> result = new ArrayList(); |
leetcode 131. Palindrome Partitioning
1 | Given a string s, partition s such that every substring of the partition is a palindrome. |
- 就是从头开始找回文串,找到一个就放进List里,再判断后面是不是回文串就行了。
- 回溯都是有模板的,先把模板写出来,然后再填充具体需要判断的内容,就会思路清晰很多。
1 | List<List<String>> res = new ArrayList(); |
leetcode 842. Split Array into Fibonacci Sequence
1 | Given a string S of digits, such as S = "123456579", we can split it into a Fibonacci-like sequence [123, 456, 579]. |
try catch
主要是应对字符串长度过长,超出整数的范围。本来写了三重循环,因为不知道初始的那两个元素怎么加到res里。后来发现:
if(res.size()<2||res.get(len-1)+res.get(len-2)==value)
,用res.size()<2
判断一下就行了呀
1 | List<Integer> res = new ArrayList(); |