combination系列
77 定长组合,可剪枝(没弄懂)
78 子集问题,找出所有长度的组合
90 78去重
39 和为定值+剪枝
40 39去重
216 定长+和为定值
总结:递归结束条件一般是cur的长度或者总和满足条件了;子集问题就无需判断递归是否要return了,直接追加到ans里;组合去重的方法是避免在同一层重复使用相同的元素。
//combination定长模板
const combination = function(nums, deep, n, startIndex, cur, ans){
if(deep === n){
ans.push(cur.slice());
return;
}
//下一次只能取后面的数
for(let i = startIndex; i < nums.length; i++){
cur.push(nums[i]);
combination(nums, deep+1, n, i+1, cur, ans);
cur.pop();
}
}
时间复杂度:O(branches^deep)
空间复杂度:O(deep)
permutation系列
46 基础题
47 46去重,比组合去重稍微复杂一点
//permutation模板
const permutation = function(nums, deep, n, used, cur, ans){
if(deep === n){
ans.push(cur.slice());
return;
}
for(let i = 0; i < nums.length; i++){
if(used[i]) continue;
used[i] = true;
cur.push(nums[i]);
permutation(nums, deep+1, n, used, cur, ans);
cur.pop();
used[i] = false;
}
}
时间复杂度:O(n!)
空间复杂度:O(n)
DFS系列
301 remove invalid parentheses
79 Word Search time complecity: O(mn4^len(word)) space: O(m*n + len(word))
**212 ****Word Search ****II **可以用字典树?
**37 **Sudoku Solver
BFS系列
**127 Word Ladder ** 单向BFS time complecity: O(|wordList|*len(beginWord)*26) space: O(|wordList|) 双向BFS
752. Open the Lock BFS/双向BFS time complecity: O(8*10000)
542. 01 Matrix BFS模板
Patition系列
93. Restore IP Addresses 定长dfs
131. Palindrome Partitioning 和子集问题相似,本质DFS
**698. Partition to K Equal Sum Subsets **dfs变型
842. Split Array into Fibonacci Sequence DFS搜索, 特点时一旦找到一个解就返回它,此时dfs返回值类型应该是true/false
总结:划分一个字符串的所有方法和枚举一个数组的所有子集过程是一样的,时间复杂度O(2^n),不同的是处理数组时startIndex会随着i增加,而对于字符串问题处理的是新的子串,所以i总是从1开始。划分字符串的方法的总数和能得到的子串的总数是不同的,后者通过一个双重循环(start, end)枚举可得。
// partition模板
const dfs = function(s, curr, ans){
if(s.length === 0){
ans.push(curr.slice());
return;
}
for(let i = 1; i <= s.length; i++){ //注意下标
const left = s.substring(0, i);
const right = s.substring(i);
if(isNotValid(left)) continue; //左子串符合一定条件,才继续分割右子串
curr.push(left);
dfs(right, curr, ans);
curr.pop();
}
}
记忆化递归
241. Different Ways to Add Parentheses 笛卡尔积(condition product)
139. Word Break DP的实质就是记忆化递归 时间O(n^2) 空间O(n)