93.复原IP地址
关键点1:结束条件,IP地址是三个点,当点有3个时终止,不过需要判断最后一个子串是否合法,如果合法,就将s放入结果集;
关键点2:合法性判断,如果合法的,就在str的后⾯插⼊⼀个逗号;然后pointSum++,递归,去掉逗号,pointSum--;
关键点3:是否合法的判断
3-1: if(start > end) 为假
3-2: if(s.charAt(start) == '0' && start != end) 为假
3-3: for循环 i = start; i <= end; i++;if(s.charAt(i) > '9' || s.charAt(i)< '0')为假
3-4: num = num * 10 + (s.charAt(i)-'0'); if(num > 255)为假;
3-5:以上都不对,则为真;
class Solution {
List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if (s.length() > 12) return res; // 算是剪枝了
backStracking(s,0,0);
return res;
}
public void backStracking(String s,int startIndex,int pointSum){
// 终止条件
if(pointSum == 3){
if(isIegal(s,startIndex,s.length()-1)){
res.add(s);
}
return;
}
// 单层循环条件
for(int i = startIndex;i < s.length();i++){
//合法性判断
if(isIegal(s,startIndex,i)){
//在str的后⾯插⼊⼀个逗点
s = s.substring(0, i + 1) + "." + s.substring(i + 1);
pointSum++;
// 有逗号,所以是i+2
backStracking(s,i+2,pointSum);
s = s.substring(0, i + 1) + s.substring(i + 2);
pointSum--;
}else{
break;
}
}
}
// 是否合法
public boolean isIegal(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;
}
}
78.子集
关键点1:结束条件,当分割线到末尾时,返回;
关键点2:子集相比之前的组合,需要将每次递归的结果都放入res集,组合是只放叶子节点的值就好
关键点3:单层循环条件还是一样的,加入,递归,弹出
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backStacking(nums,0);
return res;
}
public void backStacking(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]);
backStacking(nums,i+1);
path.remove(path.size()-1);
}
}
}
90.子集II
关键点1:与子集的区别在于数组元素有重复的,所以需要添加去重的操作;
关键点2:结束条件,当分割线到末尾时,返回;
关键点3:子集相比之前的组合,需要将每次递归的结果都放入res集,组合是只放叶子节点的值就好;
关键点4:单层循环条件还是一样的,加入,used[i] = 1,递归,弹出,used[i] = 0。
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
int[] used = new int[nums.length];
backStracking(nums,used,0);
return res;
}
public void backStracking(int[] nums,int[] used,int startIndex){
res.add(new ArrayList<>(path));
// 终止条件
if(startIndex >= nums.length){
return;
}
// 单层循环逻辑
for(int i = startIndex;i < nums.length;i++){
// 去重
if( i > 0 && nums[i] == nums[i - 1] && used[i - 1] == 0){
continue;
}
path.add(nums[i]);
used[i] = 1;
backStracking(nums,used,i+1);
path.remove(path.size()- 1);
used[i] = 0;
}
}
}