题目
文章讲解
视频讲解
思路:去重原则:元素,树层不可以重复取,树枝可以。hash这种去重方式不需要回溯
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new LinkedList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backTracing(nums, 0);
return result;
}
private void backTracing(int[] nums, int startIndex) {
if (path.size() > 1) {
result.add(new ArrayList(path));
}
HashSet<Integer> hash = new HashSet<>();
for (int i = startIndex; i < nums.length; i++) {
if (!path.isEmpty() && path.get(path.size() - 1) > nums[i] || hash.contains(nums[i]))//path不为空且比nums中元素大或者之前已在本树层存在过
continue;//后续还要接着进行比较
hash.add(nums[i]);//只记录每层的元素是否用过
path.add(nums[i]);
backTracing(nums, i + 1);
path.removeLast();
}
}
}
题目
文章讲解
视频讲解
思路:used[i]这种去重方式需要回溯
注意比较两种去重方式 permute(排列)
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new LinkedList<>();
boolean[] used;
public List<List<Integer>> permute(int[] nums) {
if (nums.length == 0)
return result;
used = new boolean[nums.length];
permuteHelper(nums);
return result;
}
private void permuteHelper(int[] nums) {
if (path.size() == nums.length) {
result.add(new ArrayList(path));
//return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i])
continue;
used[i] = true;
path.add(nums[i]);
permuteHelper(nums);
path.removeLast();
used[i] = false;
}
}
}
题目
文章讲解
视频讲解
思路:去重之前一定做排序,used[i-1] == false(对树层进行去重(视频中讲是一个回溯过程,但还需再理解))或used[i-1] == true(对树枝进行去重)
class Solution {
List<List<Integer>> result = new ArrayList<>(); // 存储最终结果的列表
List<Integer> path = new LinkedList<>(); // 存储当前路径的列表
boolean[] used; // 用于标记元素是否被使用过的布尔数组
public List<List<Integer>> permuteUnique(int[] nums) {
used = new boolean[nums.length]; // 初始化used数组
Arrays.fill(used, false); // 将used数组全部初始化为false
Arrays.sort(nums); // 对输入数组进行排序
permuteHelper(nums, used); // 调用辅助方法进行排列
return result; // 返回最终结果
}
private void permuteHelper(int[] nums, boolean[] used) {
if (path.size() == nums.length) { // 如果当前路径长度等于输入数组长度
result.add(new ArrayList<>(path)); // 将当前路径添加到最终结果中
return; // 返回
}
for (int i = 0; i < nums.length; i++) { // 遍历输入数组
if (i > 0 && nums[i] == nums[i - 1] && used[i-1] == false) // 如果当前元素与前一个相同且前一个未被使用
continue; // 跳过当前循环
if(used[i] == false){ // 如果当前元素未被使用
used[i] = true; // 标记当前元素为已使用
path.add(nums[i]); // 将当前元素添加到路径中
permuteHelper(nums, used); // 递归调用辅助方法
path.removeLast(); // 移除路径中的最后一个元素
used[i] = false; // 标记当前元素为未使用
}
}
}
}
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new LinkedList<>();
boolean[] used;
public List<List<Integer>> permuteUnique(int[] nums) {
used = new boolean[nums.length];
Arrays.fill(used, false);
Arrays.sort(nums);
permuteHelper(nums, used);
return result;
}
private void permuteHelper(int[] nums, boolean[] used) {
if (path.size() == nums.length) {
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (i > 0 && nums[i] == nums[i - 1] && used[i-1]==true)
continue;
if(used[i] == true) continue;//used出现过便不可再取
used[i] = true;
path.add(nums[i]);
permuteHelper(nums, used);
path.removeLast();
used[i] = false;
}
}
}