90. Subsets II

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums); /////
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> tmp = new ArrayList<>();
        dfs(result, tmp, 0, nums);
        return result;
        
    }
    private void dfs(List<List<Integer>> result, List<Integer> tmp, int index, int[] nums){
        if(index == nums.length){
            result.add(new ArrayList<>(tmp)); // must new an objedct here 
            return;
        }
        
        // pick at this index 
        // dfs(result, tmp.add(nums[index]), index + 1, nums);
        //Line 17: error: incompatible types: boolean cannot be converted to List<Integer>
        // https://stackoverflow.com/questions/28728648/type-mismatch-cannot-convert-from-boolean-to-int
        // add return boolean, i have to add the element first and then use it . java 
        tmp.add(nums[index]);  // add the element first and then pass it as parameter, otherwise would be boolean
        dfs(result, tmp, index + 1, nums);
        // tmp changed, backtrack recovery
        tmp.remove(tmp.size() - 1);
        
        // if duplicates exist, skip the no pick at all the index of same value. use while here 
        // becareful with the boundary
        while(index + 1 < nums.length && nums[index] == nums[index + 1]){
            index++;
        }
    
        
        // not pick at this index 
        dfs(result, tmp, index + 1, nums);
    }
}

 

 

 

 

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]


idea: similar to all subsets I, except this one has duplicates. All subsets I used "pick at current element, not pick at the current element"
in this problem, we still use pick at current element, not pick at current element stretegy. the difference is that we want to skip the second
2, in the case of [1,2,2, 3].
for example , if we suppose there is no duplicate
then we have
            O
          / . \
        1        O
       / \       / \
      2   O (a) 2 O
     / \ . /\ . /\ /\
    2 . O . 2 O (b)  2 O 2 O
   /\ . /\ ./\ /\ . /\/\/\ /\
  3 .0 3 0 3 03 0 303030 3 0

in this case, we want to skip the 1 0 2 path. we still want to get 1003 and 1000
in code , this is how we skip the not add (a), went strright to not add(b)

while(index + 1 < nums.length && nums[index] == nums[index + 1]){ index++;






API: 

 

Sb : stringbuilder  

 

sb.deleteCharAt(index)

delete last char of stringbuilder 

 

sb.deleteCharAt(sb.length() -1)

 

Another way to set the sb to original length 

Int len = sb.length()

 

sb.setLength(len)

 

char[] chars = string.toCharArray(); 

 

 

List<Integer> tmp = new ArrayList<>();

 result.add(new ArrayList<>(tmp)); 

tmp is a reference, so new a object and add it to the result 

 

Always return after base case, otherwise would stay in the loop forever 

 

posted on 2018-07-18 07:46  猪猪&#128055;  阅读(104)  评论(0)    收藏  举报

导航