代码随想录算法训练营第28天 | 93.复原IP地址,78. 子集,90. 子集 II
93.复原IP地址
- 分割问题比较类似 自己构造一个函数用于判断分割条件
- 递归函数的参数一般为 startindex 或者 某些计数参数 或者 记录元素是否用过的数组
- 终止条件 一般为startindex走到字符串最后 或者 是完成了分割任务
- 每层递归时 首先判断条件 符合就 先进行分割操作 然后添加进数组
- 然后进入下一层递归 更新startindex
- 出来的时候回溯 即 删除原来添加进去的值
class Solution {
List<String> result = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
backtracing(s,0,0);
return result;
}
public void backtracing(String s, int startIndex, int pointSum){
if(pointSum==3){
if(isValid(s,startIndex,s.length()-1)){
result.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);
pointSum++;
backtracing(s,i+2,pointSum);
pointSum--;
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){
return false;
}
int num = 0;
for(int i=start;i<=end;i++){
if(s.charAt(i)<'0' || s.charAt(i)>'9'){
return false;
}
num = num*10 + (s.charAt(i)-'0');
if(num>255){
return false;
}
}
return true;
}
}
78. 子集
- 求子集 每一层递归函数的结果都加入结果集
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backtracing(nums,0);
return result;
}
public void backtracing(int[] nums, int startIndex){
result.add(new ArrayList<>(path));
for(int i=startIndex; i<nums.length;i++){
path.add(nums[i]);
backtracing(nums,i+1);
path.remove(path.size()-1);
}
return;
}
}
90. 子集 II
- 此题是子集 和 树层去重 的应用
- 树层去重 可以用一个 boolean[]数组来记录 每次递归记录used[i]
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
boolean[] used = new boolean[nums.length];
Arrays.fill(used,false);
Arrays.sort(nums);
backtracing(nums,0,used);
return result;
}
public void backtracing(int[] nums, int startIndex, boolean[] used){
result.add(new ArrayList<>(path));
for(int i=startIndex;i<nums.length;i++){
if(i>0 && nums[i]==nums[i-1] && used[i-1]==false){
continue;
}
used[i]=true;
path.add(nums[i]);
backtracing(nums,i+1,used);
used[i]=false;
path.remove(path.size()-1);
}
return;
}
}