复原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;
}
}