力扣93.复原IP地址
链接: link
思路
判断递归回溯停止条件用分段数判断,当点数==3则表示分成了四段,最后不要忘记对第四段做一次有效性判断。
class Solution {
List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
StringBuilder sb = new StringBuilder(s);
backTrace(sb, 0, 0);
return res;
}
void backTrace(StringBuilder sb, int start, int dotcnt) {
// 退出条件
if (dotcnt == 3) {
// 检查第四段是否有效
if (isValid(sb, start, sb.length() - 1)) {
res.add(sb.toString());
}
return;
}
for (int i = start; i < sb.length(); i++) {
if (isValid(sb, start, i)) {
sb.insert(i + 1, '.');// 添加点
backTrace(sb, i + 2, dotcnt + 1);// 因为添加了.所以i+2
sb.deleteCharAt(i + 1);
} else {
break;
}
}
}
boolean isValid(StringBuilder sb, int start, int end) {
if (start > end) {
return false;
}
if (sb.charAt(start) == '0' && start != end) {// x.0.x.x => 有效 x.011.x.x => 无效
return false;
}
int num = 0;
for (int i = start; i <= end; i++) {
int digit = sb.charAt(i) - '0';
num = num * 10 + digit;
if (num > 255) {
return false;
}
}
return true;
}
}
相似题型
78.子集
思路
如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。
那么既然是无序,取过的元素不会重复取,写回溯算法的时候,for就要从startIndex开始,而不是从0开始!
链接: link
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backTrace(nums,0);
return res;
}
void backTrace(int[] nums,int start){
res.add(new ArrayList<>(path));
if(start > nums.length){
return;
}
for(int i = start;i<nums.length;i++){
path.add(nums[i]);
backTrace(nums,i+1);
path.remove(path.size() - 1);
}
}
}