数字字符串转化成IP地址

107 阅读1分钟

描述

现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。

例如:

给出的字符串为"25525522135",

返回["255.255.22.135", "255.255.221.35"]. (顺序没有关系)

数据范围:字符串长度 0≤n≤120≤n≤12

要求:空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!)

注意:ip地址是由四段数字组成的数字序列,格式如 "x.x.x.x",其中 x 的范围应当是 [0,255]。

示例1

输入:

"25525522135"

返回值:

["255.255.22.135","255.255.221.35"]

示例2

输入:

"1111"

返回值:

["1.1.1.1"]

示例3

输入:

"000256"

返回值:

[]

求解思路
使用递归的思想,把数字字符串进行分割,然后在分割的基础上面继续分割,如果遇到不符合IP地址的格式,则这一“分支”的递归就结束,然后再看其他分割的结果。
其中参考杭电 De梦的终止条件和段位合法性,我们有:当IP地址的点的数量达到3个时,停止递归。对于段位的合法性,可以参考方法一的暴力法求解,即不能出现格式不符合IP地址的数字组合。

import java.util.ArrayList;

public class Solution {
    public ArrayList<String> restoreIpAddresses(String s) {
        ArrayList<String> res = new ArrayList<>();
        ArrayList<String> ip = new ArrayList<>();  //存放中间结果
        dfs(s, res, ip, 0);
        return res;
    }
    
    private void dfs(String s, ArrayList<String> res, ArrayList<String> ip, int start){
        if(ip.size() == 4 && start == s.length()){  //找到一个合法解
            res.add(ip.get(0) + '.' + ip.get(1) + '.' + ip.get(2) + '.' + ip.get(3));
            return;
        }
        if(s.length() - start > 3 * (4 - ip.size()))  //剪枝
            return;
        if(s.length() - start < (4 - ip.size()))  //剪枝
            return;
        int num = 0;
        for(int i = start; i < start + 3 && i < s.length(); i++){
            num = num * 10 + (s.charAt(i) - '0');
            if(num < 0 || num > 255)  //剪枝
                continue;
            ip.add(s.substring(start, i + 1));
            dfs(s, res, ip, i + 1);
            ip.remove(ip.size() - 1);
            
            if(num == 0)  //不允许前缀0
                break;
        }
    }
}

复杂度分析
时间复杂度:递归所消耗的时间,为O

空间复杂度:递归使用的空间,O(N)