补一题:
131. 分割回文串
中等
给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是 回文串 。返回 s
所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = "aab" 输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a" 输出:[["a"]]
提示:
1 <= s.length <= 16
s
仅由小写英文字母组成
class Solution {
List<List<String>> res = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
public List<List<String>> partition(String s) {
backTracking(s,0);
return res;
}
private void backTracking( String s, int startIndex){
if(startIndex>= s.length()){
res.add(new ArrayList<>(path));
return;
}
for(int i = startIndex; i< s.length(); i++){
if(isPartition(s,startIndex,i)){
String str= s.substring(startIndex,i+1);
path.add(str);
}else continue;
backTracking(s,i+1);
path.removeLast();
}
}
private boolean isPartition(String s, int startIndex, int endIndex){
for(int i = startIndex, j =endIndex; i<j ; i++, j--){
if(s.charAt(i)!=s.charAt(j)){
return false;
}
}
return true;
}
}
小结:
1。这里注意分割线其实是和组合一样,就是startIndex
2.关键点是,子字符串其实是 [startIndex, i ] 想清楚这一点,就做出大半了
3.backtracking 是纵向深度递归,由startIndex控制,这里backTracking(s,i+1); i+1 说明不能重复选取
4.for循环,是广度历遍,由i主控。同时for( int i = startIndex; i< s.length(); i++) 中 i起始是由startIndex 控制,避免广度上的重复,
5.需要总结复盘最近几天的回溯,理解分清这些变量参数的改变,代表的运算逻辑变化
93. 复原 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 地址。
给定一个只包含数字的字符串 s
,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s
中插入 '.'
来形成。你 不能 重新排序或删除 s
中的任何数字。你可以按 任何 顺序返回答案。
class Solution {
List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if(s.length()>12) return res;
backTracking(s,0,0);
return res;
}
private void backTracking(String s, int idx, int pointSum){
if(pointSum==3){
if(isValid(s,idx,s.length()-1)){
res.add(s);
}
return;
}
for(int i =idx; i<s.length();i++){
if(isValid(s,idx,i)){
s=s.substring(0,i+1)+"."+s.substring(i+1);
pointSum++;
backTracking(s,i+2,pointSum);
s=s.substring(0,i+1)+s.substring(i+2);
pointSum--;
}else{
break;
}
}
}
private Boolean isValid(String s, int start, int end){
if(start>end) {
return false;
}
if(s.charAt(start)=='0'&&start!=end){
return false;
}
int num=0;
for(int i=start; i<=end; i++){
if (s.charAt(i) > '9' || s.charAt(i) < '0') {
return false;
}
num =num*10+(s.charAt(i)-'0');
if(num>255){
return false;
}
}
return true;
}
}
小结:
1.类似于 组合,但是这里分割string ,终止条件是 3个顿号,就终止,同时要判断最后一段曼珠条件吗,满足就放入res
2.这里可以用stringbuffer,麻烦一点,但是可以省新建string的空间,这里用string.substring()方法。注意加“.” 就会造成下一次递归,就是i+2
s=s.substring(0,i+1)+"."+s.substring(i+1) 这里要再理解一下
3.注意递归参数逻辑, 以及字串这里其实就是[index,i]
4. isValid 是boolean 类型返回值
5.char 与数字的转换
int num=0;
for(int i=start; i<=end; i++){
if (s.charAt(i) > '9' || s.charAt(i) < '0') {
return false;
}
num =num*10+(s.charAt(i)-'0');
if(num>255){
return false;
}