题目地址:LeetCode 77.子集II
1.问题思路
子集问题是回溯的经典题型。题目要求结果集不能存在重复的子集,如果采用先把所有结果给收集起来,然后进行去重,该方法的时间复杂度较高。所以当前在dfs查找前进行剪枝。
剪枝case:
① 对每层分支集合遍历前,需要进行判断之前的分支是否已经走过。这里为了更好去除重复的分支,需要对原数组进行排序。
②进行深度遍历时,需要记录已经使用过的数字。如果当前数字已经使用过,需要进行剪枝。
2.代码实现
class Solution {
LinkedList<List<Integer>> result = new LinkedList<>();
LinkedList<Integer> item = new LinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
result.add(item);
// 记录DFS路径使用过的元素
boolean[] used = new boolean[nums.length];
dfs(nums, used, 0);
return result;
}
public void dfs(int[] nums, boolean[] used, int startIndex) {
if (startIndex >= nums.length) {
return;
}
// 水平遍历
for (int i = startIndex; i < nums.length; i++) {
// 剪枝
if (i>startIndex && nums[i] == nums[i-1] ){
continue;
}
if (used[i]) {
continue;
}
used[i] = true;
item.add(nums[i]);
System.out.println("dfs前:" + item);
result.add(new ArrayList<>( ));
dfs(nums, used, i+1);
item.removeLast();
used[i] = false;
System.out.println("dfs后:" + item);
}
}
}
本文介绍了如何使用回溯算法解决LeetCode中的子集II问题,重点在于通过排序和剪枝技巧减少重复子集的生成,提高了时间效率。作者提供了Java代码实现,展示了如何在深度优先搜索中避免已访问元素的重复添加。
804

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



