复原ip地址
难度:中等
题目描述
有效 IP 地址 正好由四个整数(每个整数位于 0
到 255
之间组成,且不能含有前导 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 = “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] 的子数组,将end
从start
到n-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
的回溯
- 如果 s s s[ s t a r t : e n d start:end start:end]$ 不含有前导零且对应的整数在范围[ 0 , 255 0,255 0,255]则当前片段可能是有效 IP 地址的一个片段,将当前片段对应的整数填入数组的下标
回溯结束时,即可得到所有可能的有效 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;}
}