增量构造法--解决子集问题的利器

原题见leetcodesubSetssubsetsWithDup,本篇文章着重采用“增量构造法”,解决此类问题。当然,还有其他办法,如递归法、位向量法等。

首先看subSets题目:https://oj.leetcode.com/problems/subsets/,描述如下:

Given a set of distinct integers, S, 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 S = [1,2,3], a solution is:

[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
       采取增量构造法,意味着首先声明一个vector<vector<int> > 的变量res,首先res需要插入一个空的元素,然后每次读取res的元素个数,插入与其元素个数相同的元素。

如第一次,res.size() = 1,那么只插入一个元素;第二次,res.size() = 2,插入2个,故每次分别插入1、2、4、8...个元素。代码如下:

void subSetNoDup(vector<int> s, vector<vector<int> > &res)
{
   if(s.empty())
      return;
   sort(s.begin(), s.end());
   res.clear();
  res.resize(1);
  for(int i = 0; i < s.size(); i++)
  {
      int size = res.size();
     for(int j = 0; j < size; j++)
     {
        res.push_back(res[j]);                   /* 在res的末尾插入相同元素 */
       res.back().push_back(s[i]);           /* 在新插入的元素里,加入新的子元素 */
     }
  }
}


然后有此题目的变种:subsetsWithDup:https://oj.leetcode.com/problems/subsets-ii/,描述如下:

Given a collection of integers that might contain duplicates, S, 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 S = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
此时,数组中存在重复元素,需要“去重”。思路是:设prev是前一个元素,nxt是prev的下一个元素,且两者相等;那么在已经插入prev的前提下,nxt只有一种选择:一、和prev在一起,构造新的元素。意思就是,在之前的元素里,如不存在prev,那么nxt必须跳过这些元素。因此,需要记录上次res的元素个数,代码如下:

void subSetwithDup(vector<int> s, vector<vector<int> > &res)
{
    if(s.empty())
      return;
   sort(s.begin(), s.end());
   int previse_size = 0;
   res.clear();
   res.resize(1);
  for(int i = 0; i < s.size(); i++)
  {
     int size = res.size();
    for(int j = 0; j < size; j++)
    {
        if(i == 0 || s[i] != s[i-1] || j >= previse_size)     /* 3中情况下,可插入当前元素,最后一种是上述情况 */
          {
              res.push_back(res[j]);
              res.back().push_back(s[i]);
          }
    }
      previse_size = size;                                   /* 记录上一次res的元素个数 */
  }
}

你可能感兴趣的:(增量构造法--解决子集问题的利器)