问题描述(摘抄自LeetCode):
Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given "25525511135"
,
return ["255.255.11.135", "255.255.111.35"]
. (Order does not matter)
原文链接:https://oj.leetcode.com/problems/restore-ip-addresses/
问题解析:
本算法要求实现:将给定的数字字符串解析为有效的IP地址的格式(点分十进制),而且不要求结果的顺序。首先我们来分析一下IP地址的格式,看一下有什么规律?我们知道IP地址实质上由四个字节组成,但是为了阅读方便,通常采用点分十进制的形式,也就是说:每个字节的有效范围为:0-255(包括0和255);相邻两个字节中间插入一个点字符来分割。
知道了IP地址的形式,这个算法就好实现了。笔者首先想到的是用多层循环来实现,实质上要想实现分割,只需要确定好三个小数点的位置即可,但是有三种情况尤其需要注意:前置0的情况一定要排除,譬如:01.1.1.1、1.021.3.4;字节范围超出255的要去除,如:12.256.234.21。因此我专门写了个验证各字节的数据是否有效的函数,来处理这两种情况,还有一点就是C++里是没有直接转化为int的方法的,因此这个方法也需要自己来写。通过以上分析,代码自然就出来了,我的解决方案如下:
class Solution {
public:
int stringToInt(string s) //字符串转化为数字
{
int length = s.size();
int sum = 0;
int i = 0;
while (i < length)
{
sum = sum * 10 + s[i] - '0';
i++;
}
return sum;
}
bool isValid(string s1) //数据有效性验证
{
if (s1[0] == '0' && s1 != "0")
{
return false;
}
if(stringToInt(s1) > 255)
{
return false;
}
return true;
}
vector<string> restoreIpAddresses(string s) {
int len = s.size();
vector<string> result;
if (len < 4 || len > 12)
{
return result;
}
int i, j, k;
for (i = 1; i <= 3; i++)
for (j = i + 1; j - i <= 3; j++)
for (k = j + 1; (k - j <= 3) && (k < len); k++)
{
string temp = "";
if (len - k > 3)
{
continue;
}
if (!isValid(s.substr(0, i)) || !isValid(s.substr(i, j-i)) || !isValid(s.substr(j, k-j)) || !isValid(s.substr(k, len-k)))
{
continue;
}
temp = s.substr(0, i) + "." + s.substr(i, j-i) + "." + s.substr(j, k-j) + "." + s.substr(k, len-k);
result.push_back(temp);
}
return result;
}
};
结果分析:
那么笔者的解决方案能否通过呢,答案是肯定的,通过下面系统给出的结果分析可以看出,运行时间仅为36ms,也算是对自己努力半天的回报吧。
其他实现思路:
上面笔者给出了循环的方案,那么还有没有其他方式,当然有了,还有一种常见的方法就是使用递归来解决,不过时间会有点久的,有兴趣的可以研究一下啊。
Python解决方案:
下面我们给出相应方案的python代码,因为python里面的变量是无类型的,所以整型和字符串可以很方面的转换,还有就是python自带的字符串分割功能,所以python代码的形式会非常简单,解决方案如下:
class Solution:
# @param s, a string
# @return a list of strings
def isValid(self, l):
for li in l:
if li[0] == "0" and li != "0":
return False;
elif int(li) > 255:
return False;
return True;
def restoreIpAddresses(self, s):
length = len(s);
result = [];
for i in [1, 2, 3]:
for j in [i+1, i+2, i+3]:
for k in [j+1, j+2, j+3]:
if k >= length:
continue;
if self.isValid([s[:i], s[i:j], s[j:k], s[k:]]):
result.append(s[:i] + "." + s[i:j] + "." + s[j:k] + "." + s[k:]);
return result;
虽然说python的代码写起来非常容易,而且形式也简单,相同算法的代码长度通常都比C++要简短,但是通过系统的结果分析,我们也可以看出,同样是测试了147个案例,C++只用了32ms,而python却用了228ms。AC结果如下: