78. 子集
题目链接:78. 子集
思路:
本质上子集问题就是遍历一棵回溯树,通过保证元素之间的相对顺序不变来防止出现重复的子集,使用 start 参数控制树枝的生长避免产生重复的子集,用 track 记录根节点到每个节点的路径的值,同时在前序位置把每个节点的路径值收集起来,完成回溯树的遍历就收集了所有子集。
class Solution {
LinkedList<Integer> track = new LinkedList<>();
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
backtrack(nums, 0);
return res;
}
void backtrack(int[] nums, int start) {
res.add(new LinkedList<>(track));
for (int i = start; i < nums.length; i++) {
track.add(nums[i]);
backtrack(nums, i + 1);
track.removeLast();
}
}
}
90. 子集 II
题目链接:90. 子集 II
思路:
我们需要进行剪枝,如果一个节点有多条值相同的树枝相邻,则只遍历第一条,剩下的都剪掉,不要去遍历。体现在代码上,需要先进行排序,让相同的元素靠在一起,如果发现 nums[i] == nums[i-1],则跳过。
class Solution {
List<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> track = new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backtrack(nums, 0);
return res;
}
void backtrack(int[] nums, int start) {
res.add(new LinkedList<>(track));
for (int i = start; i < nums.length; i++) {
if (i > start && nums[i] == nums[i - 1]) {
continue;
}
track.addLast(nums[i]);
backtrack(nums, i + 1);
track.removeLast();
}
}
}
93.复原IP地址
题目链接:93. 复原 IP 地址
思路: 跟分割回文串思路类似,start作为隔板,因为是ip地址,所以只能将原字符串分成4段,point记录分了几次,当point为3的时候,说明已经分成四段,此时检查最后一段字符串是否valid。每加进一个valid,判断它是否valid,如果valid的话,加入“.“。
class Solution {
List<String> res = new LinkedList<>();
public List<String> restoreIpAddresses(String s) {
backtrack(s, 0, 0);
return res;
}
void backtrack(String s, int start, int point) {
if (point == 3) {
if (isValid(s, start, s.length() - 1)) {
res.add(new String(s));
}
return;
}
for (int i = start; i < s.length(); i++) {
if (isValid(s, start, i)) {
s = s.substring(0, i + 1) + "." + s.substring(i + 1);
point++;
} else {
continue;
}
backtrack(s, i + 2, point);
point--;
s = s.substring(0, i + 1) + s.substring(i + 2);
}
}
boolean isValid(String s, int l, int r) {
if (l > r) {
return false;
}
if (s.charAt(l) == '0' && l != r) {
return false;
}
int num = 0;
for (int i = l; i <= r; i++) {
num = num * 10 + (s.charAt(i) - '0');
if (num > 255) {
return false;
}
}
return true;
}
}