力扣0093——复原ip地址

复原ip地址

难度:中等

题目描述

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

  • 例如:"0.1.2.201""192.168.1.1"有效 IP 地址,但是 "0.011.255.245""192.168.1.312""[email protected]"无效 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 = “101023”
输出:[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“101.0.2.3”]

题解

可以使用回溯法来解题
回溯时需要记录起始下标 s t a r t start start 和片段数 c o u n t count count,使用长度为4的数组记录每个片段对应的整数,初始时 c o u n t = 0 count = 0 count=0 s t a r t = 0 start = 0 start=0,对于每个片段,只有不含有前导零且对应的整数范围在 [ 0 , 255 0,255 0,255],才可能是有效的ip地址

  • 如果 c o u n t = 4 count=4 count=4,则只有s遍历结束之后才能得到有效的ip地址,当 s t a r t = n start=n start=n 时,字符串s遍历结束,根据数组中的整数生成ip地址并添加到答案中
  • 如果 c o u n t < 4 count<4 count<4,则当前片段对应的编号为 c o u n t count count,用end表示当前片段的结束下标,用 s s s[ s t a r t : e n d start:end start:end]$ 来表示字符串的下标范围 [ s t a r t , e n d start,end start,end] 的子数组,将endstartn-1依次遍历,执行如下操作:
    • 如果 s s s[ s t a r t : e n d start:end start:end]$ 不含有前导零且对应的整数在范围[ 0 , 255 0,255 0,255]则当前片段可能是有效 IP 地址的一个片段,将当前片段对应的整数填入数组的下标count中,继续对下一个片段回溯,下一个片段的起始下标是 e n d + 1 end + 1 end+1,下一个片段的片段数是 c o u n t + 1 count + 1 count+1
    • 如果 s s s[ s t a r t : e n d start:end start:end]$ 含前导零或对应的整数不在范围[ 0 , 255 0,255 0,255]则当前片段不可能是有效 IP 地址的一个片段,如果继续将end向右移动则当前片段一定不符合有效 IP 地址的规则,因此结束对当前start的回溯

回溯结束时,即可得到所有可能的有效 IP 地址。

想法代码

using System.Text;

class Solution
{
    int n; 
    string s; 
    static int maxAdd = 4;
    int[] ipArr = new int[maxAdd];
    IList<string> ipAddress = new List<string>();
    public static void Main(String[] args)
    {
        string s = "25525511135";
        Solution solution = new Solution();
        IList<string> ans = solution.RestoreIpAddresses(s);
        foreach (string ip in ans)
        {
            Console.WriteLine(ip);
        }
    }

    public IList<string> RestoreIpAddresses(string s)
    {
        this.n = s.Length;
        this.s = s;
        if (n < maxAdd || n > 3 * maxAdd)
        {
            return ipAddress;
        }

        BackTrack(0, 0);
        return ipAddress;
    }

    public void BackTrack(int start, int count)
    {
        if (count == maxAdd)
        {
            if (start == n)
            {
                ipAddress.Add(Convert(ipArr));
            }
        }
        else
        {
            bool flag = true;
            for (int end = start; end < n && flag; end++)
            {
                if (Valid(start, end))
                {
                    ipArr[count] = int.Parse(s.Substring(start, end - start + 1));
                    BackTrack(end + 1, count + 1);
                }
                else
                {
                    flag = false;
                }
            }
        }
    }

    public string Convert(int[] ipArr)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(ipArr[0]);
        for (int i = 1; i < maxAdd; i++)
        {
            sb.Append('.');
            sb.Append(ipArr[i]);
        }
        return sb.ToString();
    }

    public bool Valid(int start, int end)
    {
        int length = end - start + 1;
        if (length < 1 || length > 3)
        {
            return false;
        }

        if (length > 1 && s[start] == '0')
        {
            return false;
        }

        return int.Parse(s.Substring(start, end - start + 1)) <= 255;
    }
}

你可能感兴趣的:(算法进修,leetcode,tcp/ip,算法)