题目
有效 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 中的任何数字。你可以按 任何 顺序返回答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
class Solution {
List<String> ans;
int n;
int[] segments = new int[4];
public List<String> restoreIpAddresses(String s) {
//回溯法
ans = new ArrayList<>();
n= s.length();
if (n>12||n<4) return ans;//判断长度是否符合
backtrack(s,0,0);//第i个char,第j组
return ans;
}
void backtrack(String s,int i,int j){//对第i位的操作,第j段
if (i==n&&j==4){
StringBuilder res = new StringBuilder();
for (int ind = 0; ind < 4; ind++) {
res.append(segments[ind]);
if (ind!=3){
res.append(".");
}
}
ans.add(res.toString());//加入答案
return;
}else if (i>=n||j>=4){// 如果还没有找到 4 段 IP 地址就已经遍历完了字符串,那么提前回溯
return;
}
// 由于不能有前导零,如果当前数字为 0,那么这一段 IP 地址只能为 0
if (s.charAt(i)=='0'){
segments[j]=0;
backtrack(s,i+1,j+1);
}
//普通判断
int addr=0;
for (int k = i; k < n; k++) {
addr=addr*10+(s.charAt(k)-'0');
if (addr>0&&addr<256){
segments[j]=addr;//不需要递归,因为每次赋值就是剪枝
backtrack(s,k+1,j+1);
}else break;
}
}
}
要点
- 本题使用回溯法,创建长度为4的数组,表示四个段。
- 每个段的可能情况都进行递归,注意为0的情况
- 由于每次赋值都会删除旧数据,等于剪枝了