93. 复原IP地址
思路:
1. 递归参数:字符串s,搜索的起始位置startIndex,添加逗点的数量pointNum;
2. 终止条件:pointNum==3;验证第四段是否合法,如果合法就加入结果集;返回;
3. 单层搜索的逻辑:for循环所截取的子串为[startIndex,i],判断这个子串是否合法;若合法,就在字符串后面加上“.”表示已经分割,若不合法则结束循环。递归(注意下一层递归的startIndex从i+2开始,因为在字符串中加入了分隔符“.”,同时pointNum++;回溯,删掉“.”,pointNum--;
4. 判断子串是否合法:(1)段位以0为开头的数字不合法;(2)段位里有非正整数字符不合法;(3)段位大于255时不合法;
class Solution {
List<String> res = new ArrayList<>();
StringBuilder sb = new StringBuilder();
public List<String> restoreIpAddresses(String s) {
backTracking(s,0,0);
return res;
}
private void backTracking(String s, int start, int pointNum){
if(start==s.length() && pointNum==4){
res.add(sb.toString());
return;
}
if(start==s.length() || pointNum==4) return;
//剪枝:ip段的长度最大是3,且ip段处于[0,255]
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) continue;
sb.append(s.substring(start,i+1));
if(pointNum<3) sb.append(".");
pointNum++;
backTracking(s,i+1,pointNum);
pointNum--;
sb.delete(start+pointNum,i+start+2);
}
}
}
78.子集
思路:
1. 子集问题:找树的所有节点;
2. 全局变量:res,path;递归函数参数:数组nums,startIndex;
3. 递归终止条件:startIndex>=nums.length;
4. 单层搜索逻辑:path收集元素,递归,回溯;
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
backTracking(nums,0);
return res;
}
private void backTracking(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]);
backTracking(nums,i+1);
path.removeLast();
}
}
}
90.子集II
思路:
1. 子集问题:找树的所有节点;去重【同一树层】;
2. 全局变量:res,path;递归函数参数:数组nums,startIndex;
3. 递归终止条件:startIndex>=nums.length;
4. 单层搜索逻辑:path收集元素,递归,回溯;
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backTracking(nums,0);
return res;
}
private void backTracking(int[] nums, int start){
res.add(new ArrayList<>(path));
for(int i=start;i<nums.length;i++){
if(i>start && nums[i]==nums[i-1]) continue;
path.add(nums[i]);
backTracking(nums,i+1);
path.removeLast();
}
}
}