题目描述:
有效 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)
思路:思路不清晰,很难的一道题!
1)最重要:需要一个记录 . 出现次数的数字,其不能出现超过4次!
2)在原有的 字符串上进行更改,不需要额外的StringBuilder,弄清楚 下标位置就好!
3)判断切分的字符串是否合适的方法,要写出来,并且写正确!
第二种方法看代码随想录;各个细节不好处理!
代码:
1)回溯:代码回想录思路
class Solution {
List<String> res = new ArrayList<>();
//重要的一点,需要判断一下,.的数量!
//需要一个额外的方法,判断每段的字符串是否合法!
//一个理解错的点,要么一段只有 一个 0 ,不会有 00 的情况,该情况也是错的!
public List<String> restoreIpAddresses(String s) {
back(s,0,0);
return res;
}
//在原有的字符串上进行 递归和回溯
void back(String s,int start,int num){
//已经有了三个点,判断第四段是否合适
if(num == 3){
if(isValid(s,start,s.length() - 1)){
res.add(s);
}
return;
}
for(int i = start;i < s.length();i++){
if(isValid(s,start,i)){
s = s.substring(0,i + 1) + "." + s.substring(i + 1);//生成了一个新字符串
num++;
back(s,i + 2,num);
num--;
s = s.substring(0,i + 1) + s.substring(i + 2);
}else break;
}
}
//在字符串中剪出来一段,进行判断
boolean isValid(String s,int start,int end){
if(start > end) return false;
if(s.charAt(start) == '0' && start != end) return false;
//这样的判断会溢出
if(end - start + 1 > 3) return false;
int sum = Integer.parseInt(s.substring(start,end + 1));
if(sum < 0 ||sum > 255) return false;
else return true;
}
}
2)使用StringBuilder,见代码随想录
class Solution {
List<String> res = new ArrayList<String>();
StringBuilder strr = new StringBuilder();
public List<String> restoreIpAddresses(String s) {
back(s, 0, 0);
return res;
}
public void back(String s, int start, int number) {
if (start == s.length() && number == 4) {
res.add(str.toString());
return;
}
if (start == s.length() || number == 4) {
return;
}
for (int i = start; i < s.length() && i - start < 3 && Integer.parseInt(s.substring(start, i + 1)) >= 0
&& Integer.parseInt(s.substring(start, i + 1)) <= 255; i++) {
if (i + 1 - start > 1 && s.charAt(start) - '0' == 0) {
break;//改动,不用continue,后面肯定也全不合适
}
str.append(s.substring(start, i + 1));
if (number < 3) {
str.append(".");
}
number++;
back(s, i + 1, number);
number--;
//这一步时最难理解的:
//stringBuiler和s中的下标是不同的!
//前面有了两端,要删除第三段,就需要加上num;结尾处,i+num之后,由于右开要多加1,又由于已经加了一个 . 要再加1
str.delete(start + number, i + number + 2);//最后一个怎么办?
}
}
}