JavaScript|LeetCode|搜索|93.复原IP地址

法1:回溯
看了答案
想法:

  1. IP地址由4部分组成,四部分之间由 . 分隔,如:255.255.255.255(即11111111.11111111.11111111.11111111)
  2. 每部分>=0 && 每部分<= 255
  3. 每部分没有前导零
  4. 当前IP地址已经有4部分 && 输入的字符串已访问完最后一位,则当前IP地址是答案之一,存入
  5. 增加一个部分->继续寻找下一部分->找到所有可能的“下一部分”->删除之前衔接的一个部分(即给当前要删除部分的前一部分衔接其他可能部分的机会)
/** * @param {string} s * @return {string[]} */
var restoreIpAddresses = function(s) {    
    if(s.length == 0) {        
        return [];    
    }    
    var output = [];    
    doRestore(output, s, 1, "");    
    return output;
};

// output: 方便给结果集增加元素
// s: (剩余)输入串,每轮生成IP地址都需要
// k: 正在生成IP地址的第k部分(1, 2, 3, 4)
// partIP: 处于生成过程的IP地址,可能是结果之一function 
doRestore(output, s, k, partIP) {    
    if(k == 5 || s.length == 0) { // 已经生成了4部分,或已经没有剩余的数字供分配        
        if(k == 5 && s.length == 0) { // 两者都满足才说明↓            
            output.push(partIP); // 此时的partIP为答案之一        
        }        
        // 如果:已经生成了4部分,但s仍有数字未分配;        
        // 或如果:s没有数字可分配了,但当前IP地址未生成        
        // 以上两者满足一个,直接返回        
        return;    
    }    
    var i = 0, part = "";    
    for(i = 0; i < s.length && i < 3; i++) {        
        if(i != 0 && s.charAt(0) == '0') {             
            // IP地址的每一部分没有前导零,若当前位置不是s的第一位,但却是0            
            // 则s的第一位0独占一部分,在该部分,不可能再衔接其他数字来组成新部分了            
            break;        
        }        
        part += s.charAt(i);        
        if(Number(part) <= 255) { // IP地址的每一部分 <= 255            
            if(partIP.length > 0) { // 第一部分前没有 .                 
                part = '.' + part;            
            }            
            partIP += part;            
            doRestore(output, s.slice(i + 1), k + 1, partIP);            
            partIP = partIP.slice(0, partIP.length - part.length);            
            if(partIP.length > 0) { // 把之前加的.去掉                
                part = part.slice(1);            
            }        
        }    
    }
}

法2:暴力解法
在题解区看到的暴力解法Java写的,根据解法思想写了如下JavaScript版;这个解法绝了

/** * @param {string} s * @return {string[]} */
var restoreIpAddresses = function(s) {    
    if(s.length == 0) {        
        return [];    
    }    
    var output = [], temp = "";    
    var i = 0, j = 0, k = 0, l = 0;    
    var n1 = 0, n2 = 0, n3 = 0, n4 = 0;    
    for(i = 1; i < 4; i++) {        
        for(j = 1; j < 4; j++) {            
            for(k = 1; k < 4; k++) {                
                for(l = 1; l < 4; l++) {                    
                    if(i + j + k + l == s.length) {                        
                        n1 = Number(s.slice(0, i));                        
                        n2 = Number(s.slice(i, i + j));                       
                        n3 = Number(s.slice(i + j, i + j + k));                        
                        n4 = Number(s.slice(i + j + k));                        
                        if(n1 <= 255 && n2 <= 255 && n3 <= 255 && n4 <= 255) {                            
                            temp = "" + n1 + "." + n2 + "." + n3 + "." + n4;                            
                            if(temp.length == s.length + 3) {                                
                                output.push(temp);                            
                            }                        
                        }                    
                    }                    
                    temp = "";                
                }            
            }        
        }    
    }    
    return output;
};

个人认为这个解法的精妙之处在于利用了类型转换:字符串转换为数字之后,前导零会去除;将每部分数字与255比较之后,符合条件则用“.”衔接,再次比较生成的“IP地址”长度与[(原字符串长度)+3]。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值