字符串的分割也属于回溯问题,可以直接套回溯的模板来做,但是要注意题目中给的条件,难点在于写判断条件的那段代码。
这道题中点在于子串的分割以及判断每个子串是否是回文串
class Solution {
List<List<String>> res = new ArrayList<>();
LinkedList<String> list = new LinkedList<>();
public List<List<String>> partition(String s) {
recur(s,0);
return res;
}
public void recur(String s,int start){
if(start>=s.length()){
res.add(new ArrayList<>(list));
return;
}
for(int i = start;i<s.length();i++){
if(isTrue(s,start,i)){
String str = s.substring(start,i+1);
list.add(str);
}else{
continue;
}
recur(s,i+1);
list.removeLast();
}
}
// 判断是否是回文串
public boolean isTrue(String s,int i,int j){
while(i<j){
if(s.charAt(i)!=s.charAt(j)) return false;
i++;
j--;
}
return true;
}
}
这道题和上道题难点都是在于如何确定符合条件的子串,注意这道题添加一个新参数,用来记录字符串中放了几个点,如果放了三个点,那么直接判断该位置之后的所有数字是否符合题目要求。
class Solution {
List<String> list = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if(s.length()<4||s.length()>12) return list;
recur(s,0,0);
return list;
}
public void recur(String s,int index,int pointNum){
if(pointNum==3){
if(isTrue(s,index,s.length()-1)){
list.add(s);
}
return;
}
for(int i = index;i<s.length();i++){
if(isTrue(s,index,i)){
s = s.substring(0,i+1)+"."+s.substring(i+1);
pointNum += 1;
recur(s,i+2,pointNum);
s = s.substring(0,i+1) + s.substring(i+2);
pointNum -= 1;
}else break;
}
}
// 判断该ip地址是否合理
public boolean isTrue(String s,int i,int j){
if(i>j) return false;
// 判断多位数是否0开头
if(s.charAt(i)=='0' && i!=j) return false;
// 判断是否大于255
int sum = 0;
for(int x = i;x<=j;x++){
// 判断是否是数字
if(s.charAt(x)<'0' || s.charAt(x)>'9') return false;
int num = s.charAt(x)-'0';
sum = sum*10+num;
if(sum>255) return false;
}
return true;
}
}
这道题有几个小点需要注意:
1、字符串分割函数substring(i,j),是前闭后开。如果只有一个参数就表示截取从该位置一直到字符串末尾位置的串。要在字符串中某个位置添加字符,可以使用前后拼接方法。
2、把字符串中的多位数转为int型的多位数,会有一些蠢b(就是我)不小心写成sum +=
int sum=0;
sum = sum*10+(s.charAt(i)-'0');
3、注意回溯时的位置,因为在原字符串中i位置之后添加了点,所以下层要从i+2位置开始