[LeetCode 78 / 90] Subsets / Subsets II

LeetCode 78 Subsets

Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

Solution:Backtracking

  1. 基本上就是backtracking用来求解combination的固定写法
  2. 分别求 0 ~ n的全组合
class Solution {
    public List> subsets(int[] nums) {
        List> result = new ArrayList<> ();
        if (nums == null || nums.length == 0) {
            return result;
        }
        
        for (int i = 0; i <= nums.length; i++) {
            subsetsHelper (nums, 0, i, new ArrayList<> (), result);
        }
        
        return result;
    }
    
    private void subsetsHelper (int[] nums, int index, int k, List combinationEntry, List> result) {
        if (combinationEntry.size () == k) {
            result.add (new ArrayList<> (combinationEntry));
            return;
        }
        
        for (int i = index; i < nums.length; i++) {
            combinationEntry.add (nums[i]);
            subsetsHelper (nums, i + 1, k, combinationEntry, result);
            combinationEntry.remove (combinationEntry.size () - 1);
        }
    }
}

LeetCode90: Subset 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.

Example:

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

Solution:backtracking vs Combination

  1. 与上一题用backtracking求combination的思路一致
  2. 但需要去重。如例题中有2个重复的2。 那么求解的时候,对于重复的元素,如果它不是当前子集的出发元素,那么就要过滤掉它。
  3. 题目并未告知元素是否排过序,为了让重复的元素排在一起,首先要对数组排序。
class Solution {
    public List> subsetsWithDup(int[] nums) {
        List> result = new ArrayList<> ();
        if (nums == null || nums.length == 0) {
            return result;
        }
        
        // 题目没有说明数组已排序,所以别忘了先排序,再搜索
        Arrays.sort (nums);
        
        for (int i = 0; i <= nums.length; i++) {
            subsetsWithDupHelper (nums, 0, i, new ArrayList<> (), result);
        }
        
        return result;
    }
    
    private void subsetsWithDupHelper (int[] nums, int index, int k, List combinationEntry, List> result) {
        if (combinationEntry.size () == k) {
            result.add (new ArrayList<> (combinationEntry));
            return;
        }
        
        for (int i = index; i < nums.length; i++) {
            
            // 去重:对于所有重复元素,我们只选择第一次出现的那个。
            // 如果某位置元素和前一位置数值相同了,即nums[i] = nums[i – 1],那么就跳过该位置。
            // 通过 i > startIndex 来判断当前 i 是否是当前子集的出发位置还是后面位置 (即是否是第一次选择,比如【2,2】,如果不用这个判断,就会把【2,2】给过滤掉)。
            
            if (i > index && nums [i] == nums [i - 1]) {
                continue;
            }
            combinationEntry.add (nums[i]);
            subsetsWithDupHelper (nums, i + 1, k, combinationEntry, result);
            combinationEntry.remove (combinationEntry.size () - 1);
        }
    }
}

你可能感兴趣的:([LeetCode 78 / 90] Subsets / Subsets II)