1、题目
定一个只包含数字的字符串,用以表示一个 IP 地址,返回所有可能从 s
获得的 有效 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 地址。
示例 1:
输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]
示例 2:
输入:s = "0000"
输出:["0.0.0.0"]
示例 3:
输入:s = "1111"
输出:["1.1.1.1"]
示例 4:
输入:s = "010010"
输出:["0.10.0.10","0.100.1.0"]
示例 5:
输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
提示:
0 <= s.length <= 3000
s
仅由数字组成
2、思路
(dfs) O ( C n − 1 3 ) O(C_{n - 1}^3) O(Cn−13)
一共有4
位数字,暴力枚举4
个在[0,255]
区间合法数字,若当前枚举的数字符合条件,则从下一个位置开始枚举下一个数字
时间复杂度分析: 共有n
个数字,从n - 1
个间隔中取3
个间隔点,因此时间复杂度是
O
(
C
n
−
1
3
)
O(C_{n - 1}^3)
O(Cn−13)
3、c++代码
class Solution {
public:
vector<string> ans;
vector<string> restoreIpAddresses(string s) {
dfs(s,0,0,"");
return ans;
}
// u表示枚举到的字符串下标,k表示当前截断的IP个数,s表示原字符串
void dfs(string& s,int u, int k, string path)
{
if( u == s.size()) //搜索到了字符串终点
{
if( k == 4) //已经搜索到了4个数
{
path.pop_back(); //去除路径中最后一个'.'
ans.push_back(path);
}
return ;
}
if( k == 4) return ; //剪枝:如果还未达到字符串终点,确已经搜到了四个数,则方案不合法。
for(int i = u , t = 0; i < s.size(); i++)
{
if(i > u && s[u] == '0') break; //有前导0
t = t * 10 + s[i] - '0';
if(t <= 255) dfs(s,i + 1, k + 1,path + to_string(t) + '.');
else break;
}
}
};
4、java代码
class Solution {
static List<String> ans = new ArrayList<String>();
public List<String> restoreIpAddresses(String s) {
ans.clear();
dfs(s,0,0,"");
return ans;
}
static void dfs(String s,int u,int k,String path)
{
if(u == s.length())
{
if(k == 4)
{
ans.add(path.substring(0,path.length() - 1));//去掉"."号
}
return ;
}
if(k == 4) return ;
for(int i = u,t = 0;i < s.length();i ++)
{
if(i > u && s.charAt(u) == '0') break;//前导0
t = t * 10 + s.charAt(i) - '0';
if(t <= 255) dfs(s,i + 1,k + 1,path + t + ".");
else break;
}
}
}
原题链接: 93. 复原 IP 地址