【回溯法】-----求一个集合的子集问题

leetcode 78 问题原文

Given an integer array nums of unique elements, return all possible
subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

Example

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

Constraints:

  • 1 <= nums.length <= 10

  • 1 <= nums.length <= 10

  • All the numbers of nums are unique.

解决思路

首先这个问题,是一个求子集的问题,求子集问题可以联想到组合问题和分割问题,如果把求解后两个问题的遍历过程形式化为树,我们可以认为组合问题和分割问题是求整棵树的叶子节点的过程。子集问题也可以认为是组合问题和分割问题,但是在求得整棵数的叶子节点之后,在求集合的并集时,需要去掉重复的子集,这个过程时间复杂度有点高,可以规避。
本题给出的nums里面的元素是唯一的,为了避免节点重复被选取,在取节点的时候,每次都不能取之前已经使用过的节点,如下图所示的取节点方法:
tree
按照此方法取出的节点,最终得到的集合中的子集是不会重复的。

回溯法

回溯法一般分为三个步骤:

  1. 确定回溯过程中子方法的参数和返回值
  2. 确定子方法中的结束条件
  3. 确定子方法中进入回溯的逻辑

代码实现

#include <vector>
#include <algorithm>

using namespace std;

class leetcode78new {
    
    
public:
    vector<vector<int>> vecRes;
    vector<vector<int>> subsets(vector<int> &nums) {
    
    
        sort(nums.begin(), nums.end());
        vecRes.push_back({
    
    });
        vector<int> vec;
        innerSubsets(nums, 0, vec);
        return vecRes;
    }

    void innerSubsets(vector<int> &nums, int startIndex, vector<int> vec) {
    
    
        if(startIndex == nums.size()) {
    
    
            return;
        }
        for(int i = startIndex; i < nums.size(); ++i) {
    
    
            vec.push_back(nums[i]);
            vecRes.push_back(vec);
            innerSubsets(nums, i+1, vec);
            vec.pop_back();
        }
    }
};

猜你喜欢

转载自blog.csdn.net/sinat_28199083/article/details/130182702