Subsets II

題目
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.

For example,
If nums = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

答案

效率低的答案(sort subsets):

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Set<List<Integer>> set_of_lists = new HashSet<List<Integer>>();
        List<Integer> list = new ArrayList<Integer>();
        subsets(nums, set_of_lists, list, 0);
        return new ArrayList<List<Integer>>(set_of_lists);
    }

    public void subsets(int[] nums, Set<List<Integer>> set_of_lists, List<Integer> curr_list, int curr_index) {
        if(curr_index == nums.length) {
            List<Integer> newlist = new ArrayList<Integer>(curr_list);
            Collections.sort(newlist);
            set_of_lists.add(newlist);
            return;
        }
        curr_list.add(nums[curr_index]);
        subsets(nums, set_of_lists, curr_list, curr_index + 1);
        curr_list.remove(curr_list.size() - 1);
        subsets(nums, set_of_lists, curr_list, curr_index + 1);
    }
}

效率低的答案(sort nums then find subsets):

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Set<List<Integer>> set_of_lists = new HashSet<List<Integer>>();
        List<Integer> list = new ArrayList<Integer>();
        Arrays.sort(nums);
        subsets(nums, set_of_lists, list, 0);
        return new ArrayList<List<Integer>>(set_of_lists);
    }

    public void subsets(int[] nums, Set<List<Integer>> set_of_lists, List<Integer> curr_list, int curr_index) {
        if(curr_index == nums.length) {
            List<Integer> newlist = new ArrayList<Integer>(curr_list);
            set_of_lists.add(newlist);
            return;
        }
        curr_list.add(nums[curr_index]);
        subsets(nums, set_of_lists, curr_list, curr_index + 1);
        curr_list.remove(curr_list.size() - 1);
        subsets(nums, set_of_lists, curr_list, curr_index + 1);
    }
}

效率高的答案:
這個答案是從Subset第一題(本題是Subset II)改來的
由于產生duplicates的源頭是相同的數字把自己append到前面產生的n個list上,所以只要確保這樣的append操作不發生超過1次就好了

舉個例子
樹狀圖中第4列由于2加到了[]后面形成了[2],這樣就會跟第三列的[2] 重復
避免這種情況!


image.png
class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        ans.add(new ArrayList<Integer>());
        int size = 0, start;
        for(int i = 0; i < nums.length; i++) {
            start = (i > 0 && nums[i] == nums[i - 1]) ? size : 0;
            size = ans.size();
            for(int j = start; j < size; j++) {
                List<Integer> subset = new ArrayList<>(ans.get(j));
                subset.add(nums[i]);
                ans.add(subset);
            }
        }
        return ans;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。