93.复原IP地址
思路
回溯,确定返回条件(1.只能打四个点 2.题目给了是0-255),且题目说了,第一个数字是0的话后面必须打点(即continue),正常回溯划分就行
代码
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
find(1,n,k);
return result;
}
public void find(int startIndex,int n,int k){
if(path.size()==k){
result.add(new ArrayList<>(path));
return;
}
for(int i=startIndex;i<=n-(k-path.size())+1;i++){
path.add(i);
find(i+1,n,k);
path.removeLast();
}
}
}
78.子集
思路
回溯,因为元素各不相同,所以无需排序去重。跟之前不同的是,我们的起始循环一直是从0开始而不是startIndex,因为这是找各种组合(通过标记数组表示使用过就行),且只要进来就将路径集加入结果集中
代码
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
//Arrays.sort(nums);
find(nums,0);
return result;
}
public void find(int[] nums,int startIndex){
result.add(new ArrayList<>(path));
if(startIndex>=nums.length) return;
for(int i=startIndex;i<nums.length;i++){
path.add(nums[i]);
find(nums,i+1);
path.remove(path.size()-1);
}
}
}
90.子集II
思路
回溯,因为元素变得可重复了,所以为了保证组合不重复,将数组做排序(同样的,如果当前元素跟前一个元素相同,并且前一个元素处于未使用状态,说明这两情况相同(而非是同时取两个的情况),continue跳过),跟上面不一样,上面不重复所以不排序,从0开始循环,但是这题排了序了,那就以startIndex往后,不然就出现重复组合了。
代码
class Solution {
List<List<Integer>> result=new ArrayList<>();
List<Integer> path=new ArrayList<>();
int[] hasUsed;
public List<List<Integer>> subsetsWithDup(int[] nums) {
hasUsed=new int[nums.length];
Arrays.sort(nums);
find(nums,0);
return result;
}
public void find(int[] nums,int startIndex){
result.add(new ArrayList<>(path));
if(startIndex>=nums.length) return;
for(int i=startIndex;i<nums.length;i++){
if(i>0 && nums[i]==nums[i-1] && hasUsed[i-1]==0) continue;
path.add(nums[i]);
hasUsed[i]=1;
find(nums,i+1);
path.remove(path.size()-1);
hasUsed[i]=0;
}
}
}