491.递增子序列
初始思路:
一开始的思路比较偏向于这道题是子序列(判断递增)+去重(used数组)
题解复盘:
1)不可以用used数组,使用used数组需要首先对数组进行排序,在本题中排序会影响最终结果,所以在此选择使用set数组。(set置于for循环外用于记录每层的元素,并且add之后不用remove)
2)判断递增是和path数组的末尾元素
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backtracking(nums,0);
return result;
}
public void backtracking(int[] nums,int startindex){
if(path.size()>=2){
result.add(new ArrayList(path));
}
Set<Integer> qc = new HashSet<>();
for(int i = startindex;i<nums.length;i++){
boolean a = qc.contains(nums[i]);
if((path.size()>0&&nums[i]<path.get(path.size()-1))||a){
continue;
}
path.add(nums[i]);
qc.add(nums[i]);
backtracking(nums,i+1);
path.remove(path.size()-1);
}
return;
}
}
46.全排列
初始思路&&题解复盘:
本题是排列问题,相较于集合的思路有所不同。
最重要的就是我在本层添加了2元素,在集合中的剩余集合只有{3},在排列问题中的剩余集合是{1,3}.所以无需startidnex,但为了避免重复使用2元素,需要使用used数组进行标记。
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
int[] used = new int[nums.length];
backtracking(nums,used);
return result;
}
public void backtracking(int[]nums,int[]used){
if(path.size()==nums.length){
result.add(new ArrayList(path));
return;
}
for(int i = 0;i<nums.length;i++){
if(used[i]==0){
path.add(nums[i]);
used[i]=1;
backtracking(nums, used);
used[i]=0;
path.remove(path.size()-1);
}
}
}
}
47.全排列||
初始思路&&题解复盘:
去重方式1:
还是之前树枝不去重,数层去重的原理,如果当前元素值等于前一个元素的数值,并且前一个元素的used【i-1】=0,就直接continue;
if(i>0&&nums[i]==nums[i-1]&&used[i-1]==0){continue;}
去重方式2:
数枝去重:
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) {
continue;
}
树层去重:
相较于树层去重,数枝去重也可以得到正确答案就是效率偏低。