今日目标:
1.复原ip地址
2.求子集问题I
3.子集II(去重)
1.复原ip地址
原理:这道题的解法就是和分割回文串差不多的,可以简化成一个树形图像
每次切割完后判断切出来的是否合法,合法的话就添加'.'加入之中,所以我们判断结束的条件就是当‘.’有三个的时候,这时候判断最后一个字串是否合法,如果合法就加入结果集。
注意点: dfs(s,i+2,dot+1);这里i是+2.因为这时候已经添加了符号进去,所以这时候的串的长度和位置变化了。
class Solution {
List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
StringBuilder sb = new StringBuilder(s);
dfs(sb,0,0);
return res;
}
public void dfs(StringBuilder s , int start, int dot){
if(dot == 3){
if(isValid(s , start,s.length()-1)){
res.add(s.toString());
}
return;
}
for (int i = start; i < s.length(); i++) {
if(isValid(s,start,i)){
s.insert(i+1,'.');
dfs(s,i+2,dot+1);
s.deleteCharAt(i+1);
}else break;
}
}
//判断是否是回文串
private boolean isValid(StringBuilder s, int start, int end){
if(start > end)
return false;
if(s.charAt(start) == '0' && start != end)
return false;
int num = 0;
for(int i = start; i <= end; i++){
int digit = s.charAt(i) - '0';
num = num * 10 + digit;
if(num > 255)
return false;
}
return true;
}
}
2.求子集问题I
原理:这道题就是回溯的模板题,跟之前的题相比的特别之处是他需要收集所有的节点。
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
dfs(nums , 0);
return res;
}
public void dfs(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]);
dfs(nums,i+1);
path.remove(path.size()-1);
}
}
}
3.子集II(去重)
原理:这道题用到了2的模板并且也用到了组合II的去重操作,也就是先排序,只保留相同数的第一位为首的结果,创建一个used数组来纪录。
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean used[] ;
public List<List<Integer>> subsetsWithDup(int[] nums) {
if(nums.length == 0) return res;
Arrays.sort(nums);
used = new boolean[nums.length];
dfs(nums , 0);
return res;
}
public void dfs(int[] nums , int start){
res.add(new ArrayList<>(path));
if(start >= nums.length) return;
for (int i = start; i < nums.length; i++) {
if( i > 0 && nums[i] == nums[i-1] && !used[i-1]) continue;
path.add(nums[i]);
used[i] = true;
dfs(nums,i+1);
used[i] = false;
path.remove(path.size()-1);
}
}
}