算法 中等 | 18. 子集 II

题目描述

给定一个可能具有重复数字的列表,返回其所有可能的子集。

子集中的每个元素都是非降序的
两个子集间的顺序是无关紧要的
解集中不能包含重复子集

样例1

输入:[0]
输出:
[
  [],
  [0]
]

样例2

输入:[1,2,2]
输出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

java题解

用 ”取或不取“ 的方式进行 DFS 搜索的模板

public class Solution {
    /**
     * @param nums: A set of numbers.
     * @return: A list of lists. All valid subsets.
     */
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> subsets = new ArrayList<>();
        
        Arrays.sort(nums);
        dfs(nums, 0, -1, new ArrayList<>(), subsets);
        
        return subsets;
    }
    
    private void dfs(int[] nums,
                     int index,
                     int lastSelectedIndex,
                     List<Integer> subset,
                     List<List<Integer>> subsets) {
        if (index == nums.length) {
            subsets.add(new ArrayList<Integer>(subset));
            return;
        }
        
        dfs(nums, index + 1, lastSelectedIndex, subset, subsets);
        
        if (index > 0 && nums[index] == nums[index - 1] && index - 1 != lastSelectedIndex) {
            return;
        }
        
        subset.add(nums[index]);
        dfs(nums, index + 1, index, subset, subsets);
        subset.remove(subset.size() - 1);
    }
}

C++题解

Non-recursive version.

class Solution {
public:
    /**
     * @param nums: A set of numbers.
     * @return: A list of lists. All valid subsets.
     */
    vector<vector<int>> subsetsWithDup(vector<int> &nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> subsets = {{}};
        vector<int> indexes = {-1}; // 记录subsets中每个集合结尾元素的下标
        
        for (int i = 0; i < nums.size(); ++i) {
            int size = subsets.size();
            for (int s = 0; s < size; ++s) {
                if (i > 0 && nums[i] == nums[i-1] && indexes[s] != i-1) {
                    continue;  // 去重,如果有重复数字出现,只有前上一个数字选了才能选当前数字
                }
                subsets.push_back(subsets[s]);
                subsets.back().push_back(nums[i]);
                indexes.push_back(i);
            }
        }
        
        return subsets;
    }
};

python题解

Non-recursive version.

class Solution:
    """
    @param nums: A set of numbers.
    @return: A list of lists. All valid subsets.
    """
    def subsetsWithDup(self, nums):
        nums.sort()
        subsets = [[]]
        indexes = [-1]  # 记录subsets中每个集合结尾元素的下标
        
        for i in range(len(nums)):
            size = len(subsets)
            for s in range(size):
                if i > 0 and nums[i] == nums[i-1] and indexes[s] != i-1:
                    continue  # 去重,如果有重复数字出现,只有前上一个数字选了才能选当前数字
                subsets.append(list(subsets[s]))
                subsets[-1].append(nums[i])
                indexes.append(i)
        
        return subsets
发布了148 篇原创文章 · 获赞 19 · 访问量 3643

猜你喜欢

转载自blog.csdn.net/qq_43233085/article/details/104029818