【组合回溯】Leetcode 131. 分割回文串 93. 复原 IP 地址
---------------🎈🎈131. 分割回文串 题目链接🎈🎈-------------------
131. 分割回文串
解法 切割=组合回溯
全局变量:result存储所有path的集合,path用来记录切割过的回文子串。
递归参数:字符串s,每次递归时开始截取的位置startindex(保证不重复)
终止条件:切割线切到了字符串最后面,说明找到了一种切割方法,此时就是本层递归的终止条件。
即当startindex == 字符串长度的时候,就可以收获结果集path,并终止当前递归。
单层搜索的逻辑:for循环遍历当前层从startindex开始的所有切割位置
此时s.substring(startindex,i+1)
——[startindex, i] 就是要截取的子串。首先判断这个子串是不是回文,如果是回文,就加入在 path中。如果不是那就代表已经GG了,就可以continue跳过目前的for了。
之后递归下一层,寻找i+1为起始位置的子串
之后回溯即可
判断回文:双指针向中间遍历即可
class Solution {
List<List<String>> result = new ArrayList<>();
List<String> path = new ArrayList<>(); // 单一结果,相当于收集路径
public List<List<String>> partition(String s) {
helper(s,0);
return result;
}
public void helper(String s, int startindex){
// 终止条件: 如果起始位置等于s的大小,说明找到了一组分割方案
if(startindex == s.length()){ // 当startindex= s.length()的时候,就可以把收获的path弄到result大列表中了
result.add(new ArrayList<>(path));
return;
}
// 单层搜索的逻辑
for(int i = startindex; i < s.length(); i++){
String temp = s.substring(startindex,i+1); //每一层切出来的前半部分的子串[startindex,i]
if(judge(temp)){ // 如果是回文子串 就加入到path中
path.add(temp);
}
else{
continue;
}
helper(s,i+1); //递归:起始位置后移,寻找i+1为起始位置的子串,保证不重复
path.removeLast(); // 回溯 弹出本次已经添加的子串
}
}
public boolean judge(String s){ // 判断是不是回文串
int left = 0;
int right = s.length()-1;
while(left<=right){
if(s.charAt(left) == s.charAt(right)){
left++;
right--;
} else{
return false;
}
}
return true;
}
}
93. 复原 IP 地址
---------------🎈🎈93. 复原 IP 地址 题目链接🎈🎈-------------------
解法 切割=组合回溯
👿
Integer.parseInt( )
: string转化成int
Integer.toString( )
: int转化为string
class Solution {
List<String> result = new ArrayList<>();
List<String> temp = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if(s.length()>12 || s.length()<4) return result;
helper(s,0);
return result;
}
public void helper(String s, int start){
if(start == s.length()){
if(temp.size() !=8) return;
String tempstr = new String();
for(int i = 0; i <temp.size(); i++){
tempstr += temp.get(i);
}
result.add(tempstr.substring(0,tempstr.length()-1));
return;
}
if(temp.size()>=8) return;
for(int i = start; i < s.length(); i++){
// 保证截出来的字符串长度小于3 大于3就没必要截了
if(i-start >= 3) break;
String cut = s.substring(start,i+1); //截出(start,i+1)
// 验证截出来的长度小于3的字符串不是0开头
if(cut.length() > 1 && cut.charAt(0)=='0'){
continue;
}
// 每个整数位于 0 到 255 之间组成
if(Integer.parseInt(cut) > 255){
continue;
}
// 添加cut和.到字符串数组temp中
temp.add(cut);
temp.add(".");
helper(s,i+1);
temp.removeLast();
temp.removeLast();
}
}
}