代码随想录算法训练营第28天|93.复原IP地址、78.子集、90.子集Ⅱ
一. 回溯相关算法题
93.复原IP地址
思路
- 递归组装子串的过程中记录分割点的个数如果等于三了那么就看剩余字符组成的子串是否合法,合法的话记录返回
- 如何是否判断合法子串:
- 0开头的不合法
- 非正整数组成的不合法
- 组成的数字大于255不合法
- 另外由于排除了0开头的那么在迭代每层子数组时遇到不合法的直接递归即可,如果第一位开始就不合法那么后面的都会不合法
class Solution {
List<String> result = new ArrayList<>();
StringBuilder path = new StringBuilder();
int pointNum = 0;
public List<String> restoreIpAddresses(String s) {
if (s.length() < 4 || s.length() > 12) return result;
backTracking(s, 0);
return result;
}
public void backTracking(String s, int startIndex) {
if (pointNum == 3) {
if (isValid(s,startIndex,s.length()-1)){
path.append(s,startIndex,s.length());
result.add(path.toString());
}
}
for (int i = startIndex; i < s.length() && i - startIndex < 3; i++) {
String substring = s.substring(startIndex, i + 1);
if (isValid(s,startIndex,i)) {
int temp = path.length();
pointNum += 1;
path.append(substring).append('.');
backTracking(s, i + 1);
pointNum -= 1;
path.delete(temp, path.length());
}else break;
}
}
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) > '9' || s.charAt(i) < '0') {
return false;
}
num = num * 10 + (s.charAt(i) - '0');
if (num > 255) {
return false;
}
}
return true;
}
}
78.子集
思路
- 在组合的基础上保存的不是符合条件的集合,而是每个子集都要记录
- 将记录子集的操作放在递归函数开头,可以囊括第一层递归path为空的时候
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backTracking(nums,0);
return result;
}
public void backTracking(int[] nums, int startIndex){
result.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.remove(path.size()-1);
}
}
}
90.子集Ⅱ
思路
- 本题涉及到去重处理要明确是树层去重还是树枝去重
- 树枝去重是控制每一个子集中元素值不能重复
- 树层去重是自己中可以有值一样节点下标不一样的元素
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backTracking(nums,0);
return result;
}
public void backTracking(int[] nums, int startIndex) {
result.add(new ArrayList<>(path));
for (int i = startIndex; i < nums.length; i++) {
if (i>startIndex && nums[i] == nums[i-1]){
continue;
}
path.add(nums[i]);
backTracking(nums,i+1);
path.remove(path.size()-1);
}
}
}