回溯法
类似于枚举,向下递归尝试找到答案
找到答案尝试别的可能或返回答案
找不到答案返回上一层递归,常识其他路径
力扣 22 括号生成(回溯法)
左括号必须以正确的顺序闭合
left>=right
我们可以通过跟踪到目前为止放置的左括号和右括号的数目,只在序列仍然保持有效时才添加
如果左括号数量不大于 n,放一个左括号,右括号数量小于左括号的数量,放一个右括号。
class Solution {
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList<String>();
backtrack(ans, new StringBuilder(), 0, 0, n);
return ans;
}
public void backtrack(List<String> ans, StringBuilder cur, int open, int close, int max) {
if (cur.length() == max * 2) {
ans.add(cur.toString());
return;
}
if (open < max) {
cur.append('(');
backtrack(ans, cur, open + 1, close, max);
cur.deleteCharAt(cur.length() - 1);
}
if (close < open) {
cur.append(')');
backtrack(ans, cur, open, close + 1, max);
cur.deleteCharAt(cur.length() - 1);
}
}
}
力扣 78 子集(回溯法)
从长度开始遍历,长度为0时,是否为子集。
长度为1时,长度为2时…
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
back(0, nums, res, new ArrayList<Integer>());
return res;
}
private void back(int i, int[] nums, List<List<Integer>> res, ArrayList<Integer> tmp) {
res.add(new ArrayList<>(tmp));
for (int j = i; j < nums.length; j++) {
tmp.add(nums[j]);
back(j + 1, nums, res, tmp);
tmp.remove(tmp.size() - 1);
}
}
}