代码随想录算法训练营Day 28|93. 复原 IP 地址、 78. 子集、90. 子集 II

65 阅读2分钟

93. 复原 IP 地址

题目链接

要求:有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

  • 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245""192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

思路

本题难点主要在终止条件判断和判断是否有效IP地址,当path.length > 4时,一定不符合;path.lenght == 4 && 分割点startIndex ==s.length,此时才终止。

判断是否有效IP地址:

  • 段位以0为开头的数字不合法(单独的0合法)
  • 段位里有非正整数字符不合法
  • 段位如果大于255了不合法
var restoreIpAddresses = function(s) {
    let res = [], path = []
    function backstracking(s, startIndex){
        if(path.length > 4) return
        if(path.length == 4 && startIndex == s.length){
            res.push(path.join('.'))
            return
        }
        for(let i=startIndex; i<s.length; i++){
            if(isValid(s, startIndex, i)){
                path.push(s.slice(startIndex, i+1))
                backstracking(s, i+1)
                path.pop()
            }
            
        }
    }
    function isValid(s, start, end){
        let str = s.slice(start, end+1)
        if(+str > 255){  //大于255
            return false
        }
        if(str[0] == '0' && start != end){  //不能只str!=0 可能会有00的情况
            return false
        }
        for(let i=start; i<=end; i++){  //遇到非数字字符
            if(s[i] > '9' || s[i] < '0'){
                return false
            }
        }
        return true

    }
    backstracking(s,0)
    return res
};

78. 子集

题目链接

要求:给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

思路

本题要注意返回子集不需要终止条件,所以每次递归都先返回path再判断终止条件。

var subsets = function(nums) {
    let res = [], path = []
    function backstracking(nums, startIndex){
        res.push([...path])
        if(path.length == nums.length){
            return
        }
        for(let i=startIndex; i<nums.length; i++){
            path.push(nums[i])
            backstracking(nums, i+1)
            path.pop()
        }
    }
    backstracking(nums, 0)
    return res
};

90. 子集 II

题目链接

要求:给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

思路

本题与上题多了去重的步骤。

var subsetsWithDup = function(nums) {
    nums.sort()
    let res = [], path = []
    let used = new Array(nums.length).fill(0)
    function backstracking(nums, startIndex){
        res.push([...path])
        if(path.length == nums.length){
            return
        }
        for(let i=startIndex; i<nums.length; i++){
            if(i>0 && nums[i] == nums[i-1] && used[i-1] == 0){
                continue
            }
            path.push(nums[i])
            used[i] = 1
            backstracking(nums, i+1)
            path.pop()
            used[i] = 0
        }
    }
    backstracking(nums, 0)
    return res
};