93.复原IP地址
本期本来是很有难度的,不过 大家做完 分割回文串 之后,本题就容易很多了
class Solution {
List<String> res =new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if(s.length()>12) return res;
traversal(s,0,0);
return res;
}
public void traversal(String s,int startIndex,int dotCount){
if(dotCount==3){//关键先确定分割线有三个才合法,在判断最后一组字串数是否合法
if(isValid(s,startIndex,s.length()-1)){
res.add(s);
}
return;
}
//单层搜索逻辑(确定从哪里切割以及切割是否合法)
for(int i=startIndex;i<s.length();i++){
if(isValid(s,startIndex,i)){
//合法,在切割线位置放逗号
s=s.substring(0,i+1)+"."+s.substring(i+1);
dotCount++;
traversal(s,i+2,dotCount);//注意i+2
dotCount--;//回溯回来要--
s=s.substring(0,i+1)+s.substring(i+2);//要把每次切割好的逗号删掉,回溯之后要从下一位开始切割
}else{
break;//这个节点切割不合法不遍历了,这层return掉
}
}
}
public boolean isValid(String s,int start,int end){
if(start>end){
return false;
}
if(s.charAt(start)=='0'&& start != end){//考虑四个值都是0的情况
return false;
}
int sum=0;
for(int i=start;i<=end;i++){
// if (s.charAt(i) > '9' || s.charAt(i) < '0') { // 遇到⾮数字字符不合法
// return false;
// }
sum=sum*10+(s.charAt(i)-'0');
if(sum>255){
return false;
}
}
return true;
}
}
78.子集
子集问题,就是收集树形结构中,每一个节点的结果。 整体代码其实和 回溯模板都是差不多的。
和组合不同 这个是每个节点都要放进结果集里面
class Solution {
List<List<Integer>> res=new ArrayList<>();
LinkedList<Integer> path =new LinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
traversal(nums,0);
return res;
}
public void traversal(int[] nums,int startIndex){
res.add(new ArrayList<>(path));//空集也要返回
if(startIndex==nums.length) return;
for(int i=startIndex;i<nums.length;i++){
path.add(nums[i]);
traversal(nums,i+1);
path.removeLast();
}
}
}
90.子集II
大家之前做了 40.组合总和II 和 78.子集 ,本题就是这两道题目的结合,建议自己独立做一做,本题涉及的知识,之前都讲过,没有新内容。
class Solution {
List<List<Integer>> res =new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
boolean[] used;
public List<List<Integer>> subsetsWithDup(int[] nums) {
used=new boolean[nums.length];
Arrays.fill(used,false);
Arrays.sort(nums);
traversal(nums,0);
return res;
}
public void traversal(int[] nums,int startIndex){
res.add(new ArrayList<>(path));//与去重那个题稍微不一样
if(startIndex==nums.length) return;
for(int i=startIndex;i<nums.length;i++){
if(i>=1&&nums[i]==nums[i-1]&&used[i-1]==false){
continue;//不可以是false!!!!!
}
path.add(nums[i]);
used[i]=true;
traversal(nums,i+1);
used[i]=false;
path.removeLast();
}
}
}