• [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
  • 相关阅读:
    JS 字符串
    JS 变量
    JS 数据类型与运算符
    HTML加载动画实现
    DOM Document.readyState 属性
    html中怎么去掉input获取焦点时候的边框
    原生js获取子元素
    CSS3 Animation动画
    slice,substr和substring的区别
    a链接嵌套无效,嵌套链接最优解决办法
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5079971.html
Copyright © 2020-2023  润新知