leetcode search篇

274 阅读2分钟

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)