解题思路
求子集问题本质上是求指定的若干元素的不超固定长度的组合问题,具体来说,就是给你一个数组nums,nums.length=n,每次从nums中取出数目不超过n的元素,求所有的取法,也就是求组合
现在问题的关键是nums里有重复元素,如果还是按照78.子集的做法,最后求出来的解集肯定有重复的。所以在dfs之前,需要先对nums排序,排序后nums里相同的元素必定相邻,然后在遍历解空间树的时候,要做一个去重的操作,当遇到重复出现,也就是和前面相邻元素相同的时候,直接跳过该节点,不让它向下递归
注意“去重”操作是在同层中进行的,不同层的相同元素不能“去重”。
比如nums=[1,2,2],根节点有三个子节点,即1,2和2,
当for循环到该层的最后一个子节点,即重复出现的那个2的时候,需要及时掐断,不再向下递归;
而从该层的第一个子节点开始,即1处,向下dfs到倒数第二层,会遇到重复出现的那个2,此时是身处两个不同层的元素的比较,如果只是单纯的判断它和前面的nums元素相同就不再向下递归,那么子集[1,2,2]就产生不出来。
要实现同层比较的关键就是比较for循环里的j和回溯函数的实参i,j是当前检查元素下标;i是本层开始检查的元素下标
如果nums[j]是在同层的在for循环里重复出现的,那么j肯定大于i,否则比较的两个元素就处于不同层
class Solution {
ArrayList<List<Integer>> res=new Array