这题用Set去重即可。我觉得set真的很好用,应该优先考虑set,其次是used数组。
class Solution {
private List<List<Integer>> res = new ArrayList<>();
private List<Integer> tmp = new ArrayList<>();
private void backtracking(int[] nums, int start){
if(start == nums.length) return;
Set<Integer> set = new HashSet<>();
for(int i = start; i < nums.length; ++i){
if(isLarger(tmp, nums[i]) && set.add(nums[i])){
tmp.add(nums[i]);
if(tmp.size() > 1) res.add(new ArrayList(tmp));
backtracking(nums, i+1);
tmp.remove(tmp.size()-1);
}
}
}
private boolean isLarger(List<Integer> tmp, int num){
if(tmp.size() == 0) return true;
return tmp.get(tmp.size()-1) <= num;
}
public List<List<Integer>> findSubsequences(int[] nums) {
backtracking(nums, 0);
return res;
}
}
这题思路比较巧妙。
思路:
- 因为要“往回”加元素,所以循环条件必须每次是
i = 0. - 那么怎么记录重复加进去的元素?得用
used数组。 - 在当个元素标记使用过,后面就知道,不会在加进去相同元素了。
class Solution {
private List<List<Integer>> res = new ArrayList<>();
private List<Integer> tmp = new ArrayList<>();
private void backtracking(int[] nums, boolean[] used){
if(tmp.size() == nums.length){
res.add(new ArrayList(tmp));
return;
}
for(int i = 0; i < nums.length; ++i){
if(used[i]) continue;
used[i] = true;
tmp.add(nums[i]);
backtracking(nums, used);
tmp.remove(tmp.size()-1);
used[i] = false;
}
}
public List<List<Integer>> permute(int[] nums) {
boolean[] used = new boolean[nums.length];
Arrays.fill(used, false);
backtracking(nums, used);
return res;
}
}
有了上一题,这题并不难想。就是多一个用Set去重。
Set可以去“重复树枝”的重!如果1-1-2已经存在, 下次1-1就会被Set阻止!
class Solution {
private List<List<Integer>> res = new ArrayList<>();
private List<Integer> tmp = new ArrayList<>();
private void backtracking(int[] nums, boolean[] used){
if(tmp.size() == nums.length){
res.add(new ArrayList(tmp));
return;
}
Set<Integer> set = new HashSet<>();
for(int i = 0; i < nums.length; ++i){
if(used[i]) continue;
if(set.add(nums[i])){
tmp.add(nums[i]);
used[i] = true;
backtracking(nums, used);
tmp.remove(tmp.size()-1);
used[i] = false;
}
}
}
public List<List<Integer>> permuteUnique(int[] nums) {
boolean[] used = new boolean[nums.length];
Arrays.fill(used, false);
Arrays.sort(nums);
backtracking(nums, used);
return res;
}
}
文章介绍了如何利用回溯算法和Set数据结构来解决两种数组排列问题:非递减子序列查找和不重复排列。在非递减子序列问题中,Set用于去重;在Permutations和PermutationsII题目中,除了回溯和used数组处理重复,PermutationsII还额外使用Set避免重复的子序列。
5万+

被折叠的 条评论
为什么被折叠?



