zoukankan      html  css  js  c++  java
  • [LeetCode] Subsets I (78) & II (90) 解题思路,即全组合算法

    78. Subsets

    Given a set of distinct integers, nums, return all possible subsets.

    Note:

    • Elements in a subset must be in non-descending order.
    • The solution set must not contain duplicate subsets.

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

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

    问题: 给定一个集合,求集合元素的所有组合的情况。

    实际上就是一题求全组合的题目。

    nums[i...n) 的所有组合情况可以分为两种:包含nums[i] 的 和 不包含 nums[i] 的。

    • 包含 nums[i] 的:nums[i] 依次加到 nums[i+1...n) 的全部情况即可。
    • 不包含 nums[i] 的 :就是 nums[i+1...n) 的全部情况。

    上面的递推关系,实际上就是 DP 思路。

     1     vector<vector<int>> theset;
     2     
     3     void regardValue(int value){
     4         
     5         if (theset.size() == 0) {
     6             vector<int> tmp0;
     7             vector<int> tmp1 = {value};
     8             theset.push_back(tmp0);
     9             theset.push_back(tmp1);
    10             return;
    11         }
    12     
    13         int LofPre = (int)theset.size();
    14         
    15         for (int i = 0 ; i < LofPre; i++) {
    16             vector<int> tmp = theset[i];
    17             tmp.push_back(value);
    18             theset.push_back(tmp);
    19         }
    20     }
    21 
    22     vector<vector<int>> subsets(vector<int>& nums) {
    23         
    24         std::sort(nums.begin(), nums.end());
    25         
    26         for (int i = 0; i < nums.size(); i++) {
    27             regardValue(nums[i]);
    28         }
    29         
    30         return theset;
    31     }
    View Code

    90. Subsets II

    Given a collection of integers that might contain duplicates, nums, return all possible subsets.

    Note:

    • Elements in a subset must be in non-descending order.
    • 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],
      []
    ]

    问题:若集合中包含重复值,求所有的可能组合,即子集合。

    要求:子集合内可以有重复值,但是子集合之间不可以有重复的子集合。

    同样采用原来的思路,用 unordered_set<vector<int>> 代替 vector<vector<int>> ,就得最后结果后,再转为 vector<vector<int>> 即可。

    在实现过程中发现 unordered_set<vector<int>> 不能直接使用。在 stackoverflow 看到解法方法,增加对 vector<int> 结构进行 hash 即可使用。修改后,算法实现并通过。

     1     struct VectorHash {
     2         size_t operator()(const vector<int>& v) const {
     3             hash<int> hasher;
     4             size_t seed = 0;
     5             for (int i : v) {
     6                 seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
     7             }
     8             return seed;
     9         }
    10     };
    11     
    12 
    13     vector<vector<int>> theset;
    14     
    15     unordered_set<vector<int>, VectorHash> uniSet;
    16 
    17     void regardValue(int value){
    18     
    19         if (uniSet.size() == 0) {
    20             vector<int> tmp0;
    21             vector<int> tmp1 = {value};
    22             uniSet.insert(tmp0);
    23             uniSet.insert(tmp1);
    24             return;
    25         }
    26         
    27         unordered_set<vector<int>, VectorHash> cpSet = uniSet;
    28     
    29         unordered_set<vector<int>, VectorHash>::iterator t_iter;
    30         
    31         for (t_iter = cpSet.begin(); t_iter != cpSet.end(); t_iter++) {
    32             vector<int> tmp = *t_iter;
    33             
    34             tmp.push_back(value);
    35             uniSet.insert(tmp);
    36         }
    37     }
    38 
    39 
    40 
    41     vector<vector<int>> subsetsWithDup(vector<int>& nums) {
    42      
    43          sort(nums.begin(), nums.end());
    44     
    45         for (int i = 0; i < nums.size(); i++) {
    46             regardValue(nums[i]);
    47         }
    48                 
    49         unordered_set<vector<int>, VectorHash>::iterator t_iter;
    50         
    51         for (t_iter = uniSet.begin(); t_iter != uniSet.end(); t_iter++) {
    52             vector<int> tmp = *t_iter;
    53             theset.push_back(tmp);
    54         }
    55         
    56         return theset;
    57         
    58     }
    View Code
  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5079971.html
Copyright © 2011-2022 走看看