93. 复原 IP 地址
题目链接:https://leetcode.cn/problems/restore-ip-addresses/description/
文档讲解:https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html
状态:已完成
思路:
- 由题意可知,需要将字符串切割成多个子串,转换为 [ 0 , 255 ] [0,255] [0,255]范围内的整数。为此,需要设计一个方法,判断子串是否格式正确(无前导零;无数字外字符;有效范围内)
- 回溯算法的单层递归逻辑:从startIdx开始遍历,长度最大为3,如果子串合法,则加入path并进入下一层递归
// 整数0-255
class Solution {
List<String> result;
public List<String> restoreIpAddresses(String s) {
result = new ArrayList();
backtrack(new ArrayList(), s, 0);
return result;
}
public void backtrack(List<String> path, String s, int startIdx){
if(path.size() == 4 || startIdx == s.length()){
if(path.size() == 4 && startIdx == s.length()){
StringBuilder sb = new StringBuilder();
for(int i=0;i<3;i++)
sb.append(path.get(i)+".");
sb.append(path.get(3));
result.add(sb.toString());
}
return;
}
int end = Math.min(s.length(), startIdx+3);
for(int i=startIdx;i<end;i++){
if(judge(s, startIdx, i)){
path.add(s.substring(startIdx, i+1));
backtrack(path, s, i+1);
path.remove(path.size()-1);
}
}
}
// 不要前导零,不要非数字字符,范围属于0-255
public boolean judge(String s, int start, int end){
if(end>start && s.charAt(start) == '0')
return false;
for(int i=start;i<=end;i++){
if(s.charAt(i)<'0' || s.charAt(i)>'9')
return false;
}
int num = Integer.parseInt(s.substring(start, end+1));
return num>=0 && num <=255;
}
}
78. 子集
题目链接:https://leetcode.cn/problems/subsets/description/
文档讲解:https://programmercarl.com/0078.%E5%AD%90%E9%9B%86.html
状态:已完成
思路:通过控制子集长度进行回溯
class Solution {
List<List<Integer>> result;
public List<List<Integer>> subsets(int[] nums) {
result = new ArrayList();
result.add(new ArrayList());
for(int i=1;i<=nums.length;i++){
List<Integer> path = new ArrayList();
backtrack(path, nums, 0, i);
}
return result;
}
public void backtrack(List<Integer> path, int[] nums, int startIdx, int len){
if(path.size() == len){
result.add(new ArrayList(path));
return;
}
for(int i=startIdx;i<nums.length;i++){
path.add(nums[i]);
backtrack(path, nums, i+1, len);
path.remove(path.size()-1);
}
}
}
90. 子集 II
题目链接:https://leetcode.cn/problems/subsets-ii/description/
文档讲解:https://programmercarl.com/0090.%E5%AD%90%E9%9B%86II.html
状态:已完成
思路:为了防止重复——数组排序 + 同一层递归跳过重复元素
class Solution {
List<List<Integer>> result;
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
result = new ArrayList();
result.add(new ArrayList());
for(int i=1;i<=nums.length;i++){
backtrack(new ArrayList(), nums, 0, i);
}
return result;
}
public void backtrack(List<Integer> path, int[] nums, int startIdx, int len){
if(path.size() == len){
result.add(new ArrayList(path));
return;
}
for(int i=startIdx;i<nums.length;i++){
if(i>startIdx && nums[i] == nums[i-1])
continue;
path.add(nums[i]);
backtrack(path, nums, i+1, len);
path.remove(path.size()-1);
}
}
}