代码随想录刷题Day28 | 93. 复原 IP 地址 | 78. 子集 | 90. 子集 II
93. 复原 IP 地址
题目:
有效 IP 地址 正好由四个整数(每个整数位于 0
到 255
之间组成,且不能含有前导 0
),整数之间用 '.'
分隔。
- 例如:
"0.1.2.201"
和"192.168.1.1"
是 有效 IP 地址,但是"0.011.255.245"
、"192.168.1.312"
和"192.168@1.1"
是 无效 IP 地址。
给定一个只包含数字的字符串 s
,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s
中插入 '.'
来形成。你 不能 重新排序或删除 s
中的任何数字。你可以按 任何 顺序返回答案。
思路:
其实还是分割问题,回文串问题使用一个函数判断是否为回文串,该题则需要一个函数判断分割点是否符合ip地址规则。startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。本题我们还需要一个变量pointNum,记录添加逗点的数量,当都好为3时,说明已经划分好ip,那么判断一下第四段是否符合规则即可。
代码:
class Solution {
List<String> result = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
if(s.length() > 12) return result;
backTracking(s, 0, 0);
return result;
}
public void backTracking(String s, int start, int pointNum){
if(pointNum==3){
if(start < s.length() && isVaild(s.substring(start))){
result.add(s);
}
return;
}
for(int i = start; i < start + 3 && i < s.length(); i++){
if(isVaild(s.substring(start, i + 1))){
s = s.substring(0, i + 1) + "." + s.substring(i + 1);
pointNum++;
backTracking(s, i + 2, pointNum);
pointNum--;
s = s.substring(0, i + 1) + s.substring(i + 2);
}else{
break;
}
}
}
public boolean isVaild(String s){
if(s.length() > 1 && s.charAt(0) == '0') return false;
int num = Integer.parseInt(s);
if(num > 255) return false;
return true;
}
}
78. 子集
题目:
给你一个整数数组 nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
思路:
该题和之前回溯问题不同的地方在于,之前相当于收集树的叶子节点,本题则是收集所有的节点,更改一下path添加的逻辑即可。
代码:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backTracking(nums, 0);
return result;
}
public void backTracking(int[] nums, int start){
result.add(new ArrayList<>(path));
for(int i = start; i < nums.length; i++){
path.add(nums[i]);
backTracking(nums, i + 1);
path.remove(path.size() - 1);
}
}
}
90. 子集 II
题目:
给你一个整数数组 nums
,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
思路:
相比较于上题,多了一个去重的过程。去重的逻辑是先对数组排序,如果当前数字和前一个数字相同则跳过。
代码:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backTracking(nums, 0);
return result;
}
public void backTracking(int[] nums, int start){
result.add(new ArrayList<>(path));
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i - 1]){
continue;
}
path.add(nums[i]);
backTracking(nums, i + 1);
path.remove(path.size() - 1);
}
}
}