我又回来了!争取这个暑假把剩下的《算法训练营》刷完!
这题重点在于传递下面参数时要考虑 “.” 也占一格。
class Solution {
public List<String> res = new ArrayList<>();
public String tmp = "";
// start是即将要加的位数
private void backtracking(String s, int start, int count){
if(count == 4 && start == s.length()){
res.add(new String(tmp));
return;
}
if(count > 4) return;
if(start >= s.length()) return;
String acc = "";
//acc.length() < 4 是剪枝
for(int i = start; i < s.length() && acc.length() < 4; ++i){
acc += s.substring(i, i+1);
if(!isValid(acc)) continue;
if(count != 3) {
tmp += acc + ".";
}else{
tmp += acc;
}
backtracking(s, i+1, count+1);
if(count != 3){
tmp = tmp.substring(0, tmp.length()-acc.length()-1);
}else{
tmp = tmp.substring(0, tmp.length()-acc.length());
}
}
}
private boolean isValid(String ans){
if(ans.isEmpty() || ans.length() > 3) return false;
if(ans.charAt(0) == '0' && ans.length() > 1) return false;
int res = Integer.parseInt(ans);
if(res < 0 || res > 255) return false;
return true;
}
public List<String> restoreIpAddresses(String s) {
backtracking(s, 0, 0);
return res;
}
}
- Subsets
不算很难,重点在把每一个节点都加上,而不是只加最终的结果。
class Solution {
public List<List<Integer>> res = new ArrayList<>();
public List<Integer> tmp = new ArrayList<>();
private void backtracking(int[] nums, int start){
if(tmp.size() == nums.length){
return;
}
for(int i = start; i < nums.length; ++i){
tmp.add(nums[i]);
res.add(new ArrayList(tmp));
start++;
backtracking(nums, start);
tmp.remove(tmp.size()-1);
}
}
public List<List<Integer>> subsets(int[] nums) {
res.add(tmp);
backtracking(nums, 0);
return res;
}
}
重点在于用Set去重。
class Solution {
private List<Integer> tmp = new ArrayList<>();
private List<List<Integer>> res = new ArrayList<>();
private void backtracking(int[] nums, int start){
if(start == nums.length) return;
Set<Integer> set = new HashSet<>();
for(int i = start; i < nums.length; ++i){
if(set.add(nums[i])){
tmp.add(nums[i]);
res.add(new ArrayList(tmp));
backtracking(nums, i+1);
tmp.remove(tmp.size()-1);
}
}
}
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
res.add(tmp);
backtracking(nums, 0);
return res;
}
}
本文介绍了使用回溯法解决《算法训练营》中的两个问题:RestoreIPAddresses,强调了在处理点分十进制IP时的注意事项;以及Subsets系列问题,探讨了如何生成所有子集并处理重复元素的方法。

被折叠的 条评论
为什么被折叠?



