力扣日记1.31-【回溯算法篇】90. 子集 II

力扣日记:【回溯算法篇】90. 子集 II

日期:2023.1.31
参考:代码随想录、力扣

90. 子集 II

题目描述

难度:中等

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10

题解

class Solution {
public:
    vector<int> path;
    vector<vector<int>> results;
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        // 记得先排序!!!
        sort(nums.begin(), nums.end());
        backtracking(nums, 0);
        return results;
    }
    void backtracking(vector<int>& nums, int startindex) {
        // 不需要终止条件
        results.push_back(path);
        // for
        for (int i = startindex; i < nums.size(); i++) {
            // 去重
            if (i > startindex && nums[i] == nums[i-1]) {    // 第一个元素不用去重
                // 如果本次取出元素与上一个元素一样,则跳过该元素
                continue;
            }
            path.push_back(nums[i]);
            backtracking(nums, i + 1);
            path.pop_back();
        }
    }
};

复杂度

时间复杂度: O(n * 2^n)
空间复杂度: O(n)

思路总结

  • 本题在 78.子集 的基础上,添加了重复元素,且要对解集进行去重。去重的思路与 40.组合总和 II 完全一致。直接用if (i > startindex && nums[i] == nums[i-1])为条件跳过(continue)同一层for循环的重复元素即可(即所谓“树层去重”)
  • 记得去重前一定要对原集合进行排序!!!

你可能感兴趣的:(算法,leetcode,职场和发展)