「前端刷题」93. 复原 IP 地址

129 阅读2分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

题目

链接:leetcode-cn.com/problems/re…

有效 IP 地址 正好由四个整数(每个整数位于 0255 之间组成,且不能含有前导 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 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:

**输入:**s = "25525511135" 输出:["255.255.11.135","255.255.111.35"]

示例 2:

**输入:**s = "0000" 输出:["0.0.0.0"]

示例 3:

**输入:**s = "1111" 输出:["1.1.1.1"]

示例 4:

**输入:**s = "010010" 输出:["0.10.0.10","0.100.1.0"]

示例 5:

**输入:**s = "101023" 输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

提示:

  • 0 <= s.length <= 20
  • s 仅由数字组成

思路

var restoreIpAddresses = function (s) {
  if (s.length > 12) return []
  let result = []
  fn(s, [], result)
  return result
};

递归遍历

  • 递归结束条件:当判断到最后一段时,如果合法直接加入到结果集
  • 递归体:每一段长度可以为1、2、3,所以每次都有三种可能
function fn(remain, temp, result) {
  if (temp.length === 3) {
    regular(remain) && result.push([...temp, remain].join('.'))
    return
  }
  for (let i = 1; i < 4; i++) {
    regular(remain.substr(0, i)) && fn(remain.substr(i), [...temp, remain.substr(0, i)], result)
  }
}

是否合法需要满足以下条件:

  • 大于等于0;
  • 小于等于255
  • 如果是一位可以为0,如果超过一位,不能以0开头
/**
 * @desc 用来判断每一段是否合法
 * @param {string} s
 * @return {boolean}
 */
function regular(s) {
  if (!s.length) return false
  return 0 <= +s && +s <= 255 && (s.length > 1 ? !!+s[0] : true)
}

思路2

  1. 如果所示将这个地址看成一棵树,我们一共有四个位置,我们需要对每个位置上的数字依次进行分析。
  2. 剪枝的条件:
  • 划分的ip地址的段数>4
  • 第一个字符为0并且字符的长度>1的情况下需要剪枝,比如某一位上的IP地址为02,012就不符合
  • 某一位上的ip地址>255
  1. 需要注意的细节点,在ip地址的最后一位上没有. ,具体的代码实现为path+str+(num===3? '':'.')

代码

/**
 * @param {string} s
 * @return {string[]}
 */
var restoreIpAddresses = function(s) {
    let res=[];
    dfs(s,0,0,'');
    return res;

    function dfs(ip,idx,num,path){
      if(num>4) return;
      //当前已经划分为4段(num从0~3,所以退出条件为4)并且已经搜索到ip地址的最后一位则存入结果
      if(num ===4 && idx===ip.length){
        res.push(path);
      }
      for(let i=1;i<4;i++){
        let str=ip.substring(idx,idx+i);
        if(str[0]==='0' && str.length>1 || Number(str)>255) return;
        dfs(ip,idx+i,num+1,path+str+(num===3? '':'.'));
      }
    }
};