93 复原IP地址
https://leetcode.cn/problems/restore-ip-addresses/description/
每层放一个点,横向上有取一到三位,三种取法。
关于0的逻辑是,如果首位是0那么只能取一位,如果首位不是零,那么可以取1-255之间的数。
class Solution {
public List<String> restoreIpAddresses(String s) {
List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
dfs(result, sb, 0, 0, s);
return result;
}
private void dfs(List<String> result, StringBuilder sb, int start, int level, String s) {
if (start == s.length() || level == 4) {
if (start == s.length() && level == 4) result.add(new String(sb.deleteCharAt(sb.length() - 1)));
return;
}
int len = sb.length();
for (int end = start; end < Math.min(start + 3, s.length()); end++) { // bug out of boundary
String sub = s.substring(start, end + 1);
if (end == start && s.charAt(start) == '0' || s.charAt(start) != '0' && Integer.parseInt(sub) <= 255) {
sb.append(sub);
sb.append('.');
dfs(result, sb, end + 1, level + 1, s);
sb.setLength(len);
}
}
}
}
78 子集
https://leetcode.cn/problems/subsets/ 子集即为没有外部要求的组合,和组合77的做法是一样的,都有两种写法,不同的是没有和为sum或者k个的限制,做法一中不需要条件直接输出都是解。
class Solution { //做法一,每层取一个,一个都不取时也是解,所以在每个node前都输出
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> cur = new ArrayList<>();
dfs(nums, result, cur, 0);
return result;
}
private void dfs(int[] nums, List<List<Integer>> result, List<Integer> cur, int start) {
result.add(new ArrayList<>(cur)); //为什么这里不需要 if (start == nums.length), cur为index以后都不取的子集
for (int i = start; i < nums.length; i++) {
cur.add(nums[i]);
dfs(nums, result, cur, i + 1);
cur.remove(cur.size() -1);
}
}
}
class Solution { //做法二,每层决定取或不取第index个数
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> cur = new ArrayList<>();
dfs(result, cur, nums, 0);
return result;
}
private void dfs(List<List<Integer>> result, List<Integer> cur, int[] nums, int index) {
if (index == nums.length) {
result.add(new ArrayList<>(cur));
return;
}
dfs(result, cur, nums, index + 1);
cur.add(nums[index]);
dfs(result, cur, nums, index + 1);
cur.remove(cur.size() - 1);
}
}
90 子集II
https://leetcode.cn/problems/subsets-ii/
class Solution { //做法一
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> cur = new ArrayList<>();
Arrays.sort(nums);
dfs(result, cur, nums, 0);
return result;
}
private void dfs(List<List<Integer>> result, List<Integer> cur, int[] nums, int index) {
result.add(new ArrayList<>(cur));
for (int i = index; i < nums.length; i++) {
// 值相同的相邻树枝,只遍历第一条
if (i == index || nums[i] != nums[i - 1]) { // bug, 这里 i == index 而不是 i == 0, 对这层来说 i = index肯定可以选
cur.add(nums[i]);
dfs(result, cur, nums, i + 1);
cur.remove(cur.size() - 1);
}
}
}
}
class Solution { //做法二,取或不取,不取就相同的都不取
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> cur = new ArrayList<>();
Arrays.sort(nums);
dfs(result, cur, nums, 0);
return result;
}
private void dfs(List<List<Integer>> result, List<Integer> cur, int[] nums, int index) {
if (index == nums.length) {
result.add(new ArrayList<>(cur));
return;
}
cur.add(nums[index]);
dfs(result, cur, nums, index + 1);
cur.remove(cur.size() - 1);
while (index + 1 < nums.length && nums[index] == nums[index + 1]) {
index++;
}
dfs(result, cur, nums, index + 1);
}
}