代码随想录Day26打卡 回溯算法(2)

48 阅读1分钟

39 组合总数

dfs函数记录开始的index和当前的总和

var combinationSum = function(candidates, target) {
    const path = []
    const res = []

    function dfs(start, sum) {
        // base case 1: sum = target
        if (sum === target) {
            res.push([...path])
            return;
        }
        if (sum > target) {
            return
        }
        
        for (let i = start; i < candidates.length; i++) {
            path.push(candidates[i])
            sum += candidates[i]
            dfs(i, sum)
            sum -= candidates[i]
            path.pop()
        }
    }

    dfs(0, 0)
    return res
};

40 组合总数2

相比于39题,我们可以把数组排序,然后通过对比可以去重

var combinationSum2 = function(candidates, target) {
    candidates = candidates.sort()
    const path = []
    const res = []
    const dfs = (start, sum) => {
        if (sum === target) {
            res.push([...path])
            return
        }
        if (sum > target) {
            return
        }
        for (let i = start; i < candidates.length; i++) {
            if (i > start && candidates[i] === candidates[i-1]) {
                continue
            }
            path.push(candidates[i])
            sum += candidates[i]
            dfs(i+1, sum)
            sum -= candidates[i]
            path.pop()
        }
    }
    dfs(0, 0)
    return res
};

131 分割回文串

我们记录当前开始分割的index,然后枚举从当前index开始的所有substring,如果substring是回文串,我们就加入path并继续寻找可能的组合。但是如果不是,我们可以直接跳过这个substring

var partition = function(s) {
    const path = []
    const res = []
    const dfs = (start) => {
        if (start === s.length) {
             res.push([...path])
            return 
        }
        for (let i = start; i < s.length; i++) {
            if (!isPalindrome(s.substring(start, i + 1))) {
                continue
            }
            path.push(s.substring(start, i + 1)) 
            dfs(i + 1)
            path.pop()
        }
    }
    dfs(0)
    return res
};

function isPalindrome (word) {
    let left = 0, right = word.length - 1
    while (left <= right) {
        if (word.charAt(left) !== word.charAt(right)) {
            return false
        }
        left += 1
        right -= 1
    }
    return true
}