回溯算法part3
回溯算法part3
93. 复原 IP 地址 - 力扣(LeetCode)
这题真的很难,要考虑的方面太多了
从回溯函数的三要素入手:
- 参数: Java中有StringBuilder,可以提升效率,所以
- 参数一:元字符串的sb格式
- 参数二:startIndex
- 参数三:这个我没想出来,就是逗点的数量;同时逗点数量也作为后面函数终止条件来返回
- 终止条件:逗点数量 == 3时,因为本题需要返回ip地址,一个有效的ip一定是3个逗点
- 单层遍历逻辑:判断当前节是否有效,如果有效,就添加逗点,无效直接break终止递归
一些小细节:
-
isValid()函数的范围,可以写左闭右开,也可以左闭右闭,我写的是左闭右开
-
终止条件中,逗点为3时,还有一段ip需要添加,此时需要判断第四段ip是否合理,然后才能返回
总体代码:
class Solution {
List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
StringBuilder path = new StringBuilder(s);
backtracking(path, 0, 0);
return res;
}
public void backtracking(StringBuilder s, int startIndex, int pointNum) {
if(pointNum == 3){
if(isValid(s, startIndex, s.length())){
res.add(s.toString());
}
return;
}
for(int i = startIndex; i < s.length(); i++){
if(isValid(s, startIndex, i + 1)){
s.insert(i + 1, ".");
backtracking(s, i + 2, pointNum + 1);
s.deleteCharAt(i + 1);
}else {
break;
}
}
}
public boolean isValid(StringBuilder s, int startIndex, int endIndex) { //左闭右开
if(startIndex >= endIndex){
return false;
}else if(s.charAt(startIndex) == '0' && endIndex - startIndex != 1){
return false;
}
int sum = 0;
for(int i = startIndex; i < endIndex; i++){
int digit = (s.charAt(i) - '0');
sum = sum * 10 + digit;
}
if(sum >= 0 && sum <= 255){
return true;
}
return false;
}
}
78. 子集 - 力扣(LeetCode)
子集问题

标准模板题,并且本题不需要剪枝操作,因为需要所有子集,那就是遍历整颗树
唯一与模板不同是每个节点的子集都需要加入res,如图所示
代码如下:
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backtracking(nums, 0);
return res;
}
public 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 - 力扣(LeetCode)
40.组合总和II 和 78.子集 ,本题就是这两道题目的结合
本人做的时候已经忘了之前的题目怎么做的
重点就是同层(for循环)去重,需要提前对nums数组排序
代码如下:
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backtracking(nums, 0);
return res;
}
public void backtracking(int[] nums, int startIndex) {
res.add(new ArrayList<>(path));
if(startIndex >= nums.length){
return ;
}
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.removeLast();
}
}
}
浙公网安备 33010602011771号