每次遇到dfs,回溯这些就不会做,刷了几道题之后大概能总结出模板,后续有更多套路再补充。
public List<String> function(String s){
List<String> res = new ArrayList<String>();
dfs(res,strat,temp);
}
public void dfs(List<String> int start,StringBuilder temp){
//出口条件
if(***){
//出口时要做的事
res.add(temp.toString());
return ;
}
if(){
temp.append(); //添加一个
dfs(); //继续dfs
temp.deleteCharAt(); //回退到上一步
}
}
大概就是这样的一个模板,具体的条件根据题目要求做。
下面是几个力扣中的原题:
题目描述 Leetcode 面试题 08.07. 无重复字符串的排列组合
无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。
示例1:
输入:S = "qwe"
输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]
示例2:输入:S = "ab"
输出:["ab", "ba"]
提示:字符都是英文字母。
字符串长度在[1, 9]之间。
代码:
class Solution {
List<String> list = new ArrayList<>();
boolean[] used = new boolean[10];
public String[] permutation(String S) {
StringBuilder sb = new StringBuilder();
helper(S,sb);
String[] res = new String[list.size()];
for(int i=0;i<list.size();i++){
res[i] = new String();
res[i] = list.get(i);
}
return res;
}
public void helper(String S,StringBuilder sb){
if(sb.length()==S.length()){
list.add(sb.toString());
return ;
}
for(int i=0;i<S.length();i++){
if(!used[i]){
sb.append(S.charAt(i));
used[i] = true;
helper(S,sb);
used[i]=false;
sb.deleteCharAt(sb.length()-1);
}
}
}
}
Leetcode 面试题 08.04. 幂集
幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
代码:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new LinkedList<>();
dfs(res,new LinkedList<Integer>(),nums,0);
return res;
}
public void dfs(List<List<Integer>> res,List<Integer> temp,int[] nums,int start){
res.add(new LinkedList<>(temp));
for(int i=start;i<nums.length;i++){
temp.add(nums[i]);
dfs(res,temp,nums,i+1);
temp.remove(temp.size()-1);
}
}
}
Leetcode 面试题 08.09.括号
括号。设计一种算法,打印n对括号的所有合法的(例如,开闭一一对应)组合。
说明:解集不能包含重复的子集。
例如,给出 n = 3,生成结果为:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
代码:
class Solution {
List<String> res = new ArrayList<>();
public List<String> generateParenthesis(int n) {
StringBuilder sb = new StringBuilder();
//生成的每一个有效括号的长度都是2n
helper(0,n*2,sb);
return res;
}
public void helper(int leftCou,int n,StringBuilder sb){
//如果当前的括号已经是有效括号则加如结果集中
if(sb.length()==n){
res.add(sb.toString());
return;
}
//如果当前sb中的左括号个数大于0,则添加一个右括号,递归,左括号可加入个数-1
if(leftCou>0){
sb.append(')');
helper(leftCou-1,n,sb);
sb.deleteCharAt(sb.length()-1);
}
//如果当前还需要插入左右括号才能生成有效括号,则先插入左括号
if(n-sb.length()>leftCou){
sb.append('(');
helper(leftCou+1,n,sb);
sb.deleteCharAt(sb.length()-1);
}
}
}