93. 复原IP地址

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

示例:

输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]

方法:穷举法
思路:总共四个片段,一个片段一个片段的取,拿到所有可能,找出其中的正确解;
注意:0不能开头,只能跟在数字的后边;并且确保字符串全部分成了四段,成功加入结果集,不成功则返回继续遍历;

class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        //特殊情况
        if (s.length() > 12)
            return res;
        int[] spilts = new int[5];//各个段的起始位置,从1开始起始也就是前段的结束位置(取头不取尾);
        restore(res,s);
        return res;
    }
    //暴力法
    private void restore(List<String> res, String s) {
        //切割,不能0开头
         for(int i=0;i<s.length()-3;i++){
            String first = s.substring(0,i+1);
            if((first.length()>1 && first.startsWith("0")) || Integer.valueOf(first)>255) break;
            for(int j=i+1;j<s.length()-2;j++){
                String second = s.substring(i+1,j+1);
                if((second.length()>1 && second.startsWith("0")) || Integer.valueOf(second)>255) break;
                for(int k=j+1;k<s.length()-1;k++){
                    String third = s.substring(j+1,k+1);
                    String forth = s.substring(k+1,s.length());
                    if((third.length()>1 && third.startsWith("0")) || Integer.valueOf(third)>255) break;
                    //继续下次循环,重新划分第三和第四个字符串看是否符合;
                    if((forth.length()>1 && forth.startsWith("0")) || Integer.valueOf(forth)>255) continue;
                    res.add(first+"."+second+"."+third+"."+forth);
                }
            }
        }
    }
}

方法:dfs递归回溯
思路:用数组记录每个片段的起始位置,后一个的起始位置也就是前一个的结束位置,当分成了四个片段,并且数组最后一个元素的值和该字符串长度相等时说明成功查到了,分成四个片段了但是却没有将字符串全部完成,则返,回溯重新分割;
当数字等于0时,只能在其他数字后面,不能用来开头!
备注:参考别人解法,看得有点儿头晕!

class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        //特殊情况
        if (s.length() > 12)
            return res;
        int[] spilts = new int[5];//各个段的起始位置,从1开始起始也就是前段的结束位置(取头不取尾);
        restore(0,spilts,s,res);
        return res;
    }
    //DFS回溯法;通过确定IP地址四个分段的起始位置来确定新的IP地址
    private void restore(int level, int[] s, String ip,List<String> res) {
        //生成IP地址的长度不和原IP地址长度相同则退出
        if (level == 4 && s[4] != ip.length())
            return;
        //成功切割成四段
        if (level == 4 && s[4] == ip.length()) {
            String temp = ip.substring(s[0],s[1])+"."+ip.substring(s[1],s[2])+"."+ip.substring(s[2],s[3])+"."+ip.substring(s[3]);
            res.add(temp);
        }
        //递归
        int num = 0;//记录每一段的值
        for (int i = s[level]; i < ip.length(); i ++) {
            //每一次num的值
            num = num*10 + ip.charAt(i) - '0';
            //越界检查,当num等于0时
            if((num == 0 && i==s[level]) || (num>0 && num<=255)){  //越界检查,当num为0时,i必须与该段的开始位置相等
                s[level+1]=i+1;
                restore(level+1,s,ip,res);
                if(num == 0 && i==s[level])   //如果是0,则0后面不能有其他数字
                    break;
                continue;
            }
            break;
        }
    }    
}
点赞