代码随想录Day27打卡 回溯算法(3)

70 阅读1分钟
  1. 子集

回溯函数的参数是start,先把当前的path加入res,然后从start index开始循环,然后进入下一层回溯

var subsets = function(nums) {
    const res = [], path = []
    const dfs = (start) => {
        // 加入res,因为是一种新的集合
        res.push([...path])
        for (let i = start; i < nums.length; i++) {
            path.push(nums[i])
            dfs(i + 1)
            path.pop()
        }
    }
    dfs(0)
    return res
};
  1. 子集2 排序再跳过当前回溯层和前一个相同的元素来去重
var subsetsWithDup = function (nums) {
    nums.sort((a, b) => a - b)
    const path = [], res = []
    const dfs = (start) => {
        res.push([...path])
        for (let i = start; i < nums.length; i++) {
            // i > start to correctly skip duplicates only if
            // they are the same as the previous element in the 
            // current level of recursion. 
            if (i > start && nums[i] === nums[i - 1]) {
                continue
            }
            path.push(nums[i])
            dfs(i + 1)
            path.pop()
        }
    }
    dfs(0)
    return res
};

93 复原ip地址

start 代表的是每次分割开始的地方

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

const isValid = (str) => {
    if (str.length < 1 || str.length >3) {
        return false
    }
    if (str.length === 1) {
        return true
    }
    if (str.charAt(0) === "0") {
        return false
    }
    if (parseInt(str) >= 0 && parseInt(str) <= 255) {
        return true
    }
    return false
}