题目来源于leetcode,解法和思路仅代表个人观点。传送门。
难度:中等
用时:01:00:00 (突然就写出来了)
题目
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 ‘.’ 分隔。
示例:
输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
思路
由于是ipv4的地址格式,那么分析可以得到下面两个条件:
- 给定的字符串长度肯定在4~12之间。
- 每个段的长度在1~3之间。
这里采用了分治的思想。这里一共要把字符串拆成4段。
如果有一段符合条件(0~255),那么,就是把剩下的字符串拆成3段,以此类推。
需要注意的点:
- 如果字符串长度小于4或者大于12,返回空数组;
- 每一段应该都是要在0~255之间,且不含前导0。
代码
class Solution {
List<String> restoreIpAddresses(String s) {
List<String> ans = new ArrayList<>();
if(s.length()>12 || s.length()<4){
return ans;
}
//对于字符串s,切4次
ans = splitString(s,4);
return ans;
}
//s表示传入的字符串,num表示要进行符合切割的段数
public List<String> splitString(String s,int num){
List<String> result = new ArrayList<>();
//如果只剩下一段了,返回该串(如果满足条件)
if(num == 1){
if(isSatisfied(s)){
result.add(s);
return result;
}
}
//枚举这一段的可能取值。(3次)
for(int i=1;i<=3&&i<s.length();i++){
String temp = s.substring(0,i);
//如果该串符合条件
if(isSatisfied(temp)){
//得到子串的符合条件的切割
List<String> subResult = splitString(s.substring(i,s.length()),num-1);
//对于子串的所有符合条件的切割,加上当前的段。
for(int j=0;j<subResult.size();j++){
result.add(temp+"."+subResult.get(j));
}
}
}
return result;
}
//该字符串s是否在满足的范围内,输入的s长度为1~3
public boolean isSatisfied(String s){
int num = Integer.parseInt(s);
int length = s.length();
if(num >= 0 && num <= 255){
//判断是否含前导0
if(length == 1){
if(num>=0){
return true;
}
}else if(length == 2){
if(num >= 10){
return true;
}
}else if(length == 3){
if(num >= 100){
return true;
}
}
}
return false;
}
}
算法复杂度
时间复杂度: O(3n * s),其中n表示需要切割的段数。O(s)表示将该段和字串得到符合的切割 合并 的代价。
空间复杂度: O(n)。官方说O(n),可是我不会算(菜。