复原 IP 地址
力扣连接:93. 复原 IP 地址(中等)
1.回溯的方法
在131.分割回文串(中等) 中就提到切割问题类似组合问题。
图解步骤
关键点:
最后就是在写一个判断段位是否是有效段位了。
- 段位以0为开头的数字不合法
- 段位里有非正整数字符不合法
- 段位如果大于255了不合法
递归代码
class Solution {
List<String> result = new ArrayList<>();
LinkedList<String> tmp = new LinkedList<>();
public List<String> restoreIpAddresses(String s) {
backtracking(s, 0);
return result;
}
public void backtracking(String s, int startIndex){
if(startIndex>=s.length()&&tmp.size()==4){
StringBuilder sb = new StringBuilder();
for(int i=0;i<4;i++){
sb.append(tmp.get(i));
sb.append(".");
}
String f = sb.substring(0, sb.length()-1).toString();
result.add(f);
return;
}
for(int i = startIndex; i<s.length()
&& i-startIndex < 3
&& Integer.parseInt(s.substring(startIndex, i+1)) <= 255; i++){
String number = s.substring(startIndex, i+1);
if(isCheck(number)){
tmp.addLast(number);
}else{
continue;
}
backtracking(s, i+1);
tmp.removeLast();
}
}
public Boolean isCheck(String number){
if(number.charAt(0)=='0' && number.length()>1) return Boolean.FALSE;
return Boolean.TRUE;
}
}
子集
力扣连接:78. 子集(中等)
1.回溯的方法
组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!
图解步骤
代码
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> tmp = new LinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
backtracking(nums, 0);
return result;
}
public void backtracking(int[] nums, int startIndex){
result.add(new ArrayList<>(tmp));
if(startIndex>=nums.length){
return;
}
for(int i=startIndex; i<nums.length; i++){
tmp.add(nums[i]);
backtracking(nums, i+1);
tmp.removeLast();
}
}
}
子集 II
力扣连接:90. 子集 II(中等)
在40.组合总和II (中等)中已经详细讲解过了,和本题是一个套路。
图解步骤
关键点:
- 理解“树层去重”和“树枝去重”非常重要。
- 注意去重需要先对集合排序
代码
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> tmp = new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backtracking(nums, 0, new int[nums.length]);
return result;
}
public void backtracking(int[] nums, int startIndex, int[] used){
result.add(new ArrayList<>(tmp));
if(startIndex>=nums.length){
return;
}
for(int i=startIndex; i<nums.length; i++){
if(i>0&&nums[i]==nums[i-1]&&used[i-1]==0){
continue;
}
tmp.add(nums[i]);
used[i] = 1;
backtracking(nums, i+1, used);
used[i] = 0;
tmp.removeLast();
}
}
}