继续打卡算法题,今天学习的是LeetCode第90题子集II,这道题目是道中等题
。算法题的一些解题思路和技巧真的非常巧妙,每天看一看算法题和解题思路,我相信对我们的编码思维和编码能力有一些提升。
分析一波题目
之前学习过78题子集,本题和78题只有一个不同,就是本题中元素是可以重复的,那么我们就需要去重了。
我们可以发现,在同一层如果出现相同的需要去重
。我们可以使用boolean数组表示某个元素在某一层是否使用过。
本题解题技巧
1、通过树结构表达求子集组合的过程,对同一层的元素进行去重,避免重复的子集
2、需要去重,我们要对原数组排序
编码解决
class Solution {
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
//排序为了去重
Arrays.sort( nums );
int n = nums.length;
boolean[] used = new boolean[n];
List<Integer> subResult= new ArrayList<>();
getSubResult( subResult, 0,nums,n, used);
return result;
}
public void getSubResult( List<Integer> subResult,int start,int[] nums,int n,boolean[] used) {
//满足了组合条件,是一个子集
result.add(subResult);
//遍历到最后一个元素了,除了自己,没有其他组合了,需要结束
if(start >= n) {
return;
}
for(int i=start; i<n; i++) {
//同一层去重
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
List<Integer> tempSubResult= new ArrayList<>();
tempSubResult.addAll(subResult);
tempSubResult.add(nums[i]);
used[i] = true;
//递归
getSubResult( tempSubResult, i+1,nums,n, used);
//开始遍历下一层了
used[i] = false;
}
}
}
总结
1、子集问题,画图之后就好理解了,先理思路再画图就能比较好的求解。