Given an integer array, your task is to find all the different possible increasing subsequences of the given array, and the length of an increasing subsequence should be at least 2 .

Example:

Input: [4, 6, 7, 7]
Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]

Note:

  1. The length of the given array will not exceed 15.
  2. The range of integer in the given array is [-100,100].
  3. The given array may contain duplicates, and two equal integers should also be considered as a special case of increasing sequence.

这道题让我们找出所有的递增子序列,应该不难想到,这题肯定是要先找出所有的子序列,从中找出递增的。找出所有的子序列的题之前也接触过 Subsets 和 Subsets II,那两题不同之处在于数组中有没有重复项。而这道题明显是有重复项的,所以需要用到 Subsets II 中的解法。首先来看一种迭代的解法,对于重复项的处理,最偷懒的方法是使用 TreeSet,利用其自动去处重复项的机制,然后最后返回时再转回 vector 即可。由于是找递增序列,所以需要对递归函数做一些修改,首先题目中说明了递增序列数字至少两个,所以只有子序列个数大于等于2时,才加入结果。然后就是要递增,如果之前的数字大于当前的数字,那么跳过这种情况,继续循环,参见代码如下:

解法一:

class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
set<vector<int>> res;
vector<int> out;
helper(nums, , out, res);
return vector<vector<int>>(res.begin(), res.end());
}
void helper(vector<int>& nums, int start, vector<int>& out, set<vector<int>>& res) {
if (out.size() >= ) res.insert(out);
for (int i = start; i < nums.size(); ++i) {
if (!out.empty() && out.back() > nums[i]) continue;
out.push_back(nums[i]);
helper(nums, i + , out, res);
out.pop_back();
}
}
};

我们也可以在递归中进行去重复处理,方法是用一个 HashSet 保存中间过程的数字,如果当前的数字在之前出现过了,就直接跳过这种情况即可,参见代码如下:

解法二:

class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
vector<vector<int>> res;
vector<int> out;
helper(nums, , out, res);
return res;
}
void helper(vector<int>& nums, int start, vector<int>& out, vector<vector<int>>& res) {
if (out.size() >= ) res.push_back(out);
unordered_set<int> st;
for (int i = start; i < nums.size(); ++i) {
if ((!out.empty() && out.back() > nums[i]) || st.count(nums[i])) continue;
out.push_back(nums[i]);
st.insert(nums[i]);
helper(nums, i + , out, res);
out.pop_back();
}
}
};

下面我们来看迭代的解法,还是老套路,先看偷懒的方法,用 TreeSet 来去处重复。对于递归的处理方法跟之前相同,参见代码如下:

解法三:

class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
set<vector<int>> res;
vector<vector<int>> cur();
for (int i = ; i < nums.size(); ++i) {
int n = cur.size();
for (int j = ; j < n; ++j) {
if (!cur[j].empty() && cur[j].back() > nums[i]) continue;
cur.push_back(cur[j]);
cur.back().push_back(nums[i]);
if (cur.back().size() >= ) res.insert(cur.back());
}
}
return vector<vector<int>>(res.begin(), res.end());
}
};

我们来看不用 TreeSet 的方法,使用一个 HashMap 来建立每个数字对应的遍历起始位置,默认都是0,然后在遍历的时候先取出原有值当作遍历起始点,然后更新为当前位置,如果某个数字之前出现过,那么取出的原有值就不是0,而是之前那个数的出现位置,这样就不会产生重复了,如果不太好理解的话就带个简单的实例去试试吧,参见代码如下:

解法四:

class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
vector<vector<int>> res, cur();
unordered_map<int, int> m;
for (int i = ; i < nums.size(); ++i) {
int n = cur.size(), start = m[nums[i]];
m[nums[i]] = n;
for (int j = start; j < n; ++j) {
if (!cur[j].empty() && cur[j].back() > nums[i]) continue;
cur.push_back(cur[j]);
cur.back().push_back(nums[i]);
if (cur.back().size() >= ) res.push_back(cur.back());
}
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/491

类似题目:

Subsets

Subsets II

Maximum Length of Pair Chain

参考资料:

https://leetcode.com/problems/increasing-subsequences/

https://leetcode.com/problems/increasing-subsequences/discuss/97124/c-dfs-solution-using-unordered_set

https://leetcode.com/problems/increasing-subsequences/discuss/97134/evolve-from-intuitive-solution-to-optimal

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 491. Increasing Subsequences 递增子序列的更多相关文章

  1. 491 Increasing Subsequences 递增子序列

    给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2.示例:输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, ...

  2. [LeetCode] Increasing Subsequences 递增子序列

    Given an integer array, your task is to find all the different possible increasing subsequences of t ...

  3. LeetCode 491. Increasing Subsequences

    原题链接在这里:https://leetcode.com/problems/increasing-subsequences/ 题目: Given an integer array, your task ...

  4. 【LeetCode】491. Increasing Subsequences 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  5. 491. Increasing Subsequences增长型序列

    [抄题]: Given an integer array, your task is to find all the different possible increasing subsequence ...

  6. Leetcode 673.最长递增子序列的个数

    最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[ ...

  7. Java实现 LeetCode 673 最长递增子序列的个数(递推)

    673. 最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, ...

  8. 【leetcode】491. Increasing Subsequences

    题目如下: 解题思路:这题把我折腾了很久,一直没找到很合适的方法,主要是因为有重复的数字导致结果会有重复.最后尝试用字典记录满足条件的序列,保证不重复,居然Accept了. 代码如下: class S ...

  9. 491. Increasing Subsequences

    这种increasing xxx 题真是老客户了.. 本题麻烦点在于不能重复, 但是和之前的那些 x sum的题目区别在于不能排序的 所以.... 我还是没搞定. 看了一个Java的思路是直接用set ...

随机推荐

  1. 百度APP移动端网络深度优化实践分享(三):移动端弱网优化篇

    本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为<百度App网络深度优化系列<三>弱网优化>,感谢原作者的无私分享. 一.前言 网络优化解决的核心问题有三个 ...

  2. pixijs shader颗粒化显示贴图

    pixijs shader颗粒化显示贴图 const app = new PIXI.Application({ transparent: true }); document.body.appendCh ...

  3. (转)dnSpy 强大的.Net反编译软件

    目录 1. Debug外部引用的Dll文件2. 调试应用程序3. 修改exe文件的内容 作者:D.泡沫 一说起.net的反编译软件,大家首先想到的就是Reflector,ILSpy,dotPeek等等 ...

  4. Python - 模块 - 第十六天

    Python 模块 在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了. 为此 Python 提供了一个办法 ...

  5. python中class的总结

    思维导图文件:https://files-cdn.cnblogs.com/files/benjieming/class%E6%9C%BA%E5%88%B6.zip

  6. 运算符 &(与运算)、|(或运算)、^(异或运算)

    按位与运算符(&) 参加运算的两个数据,按二进制位进行“与”运算. 运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1; 按位或运算符( ...

  7. WinRAR命令行版本 rar.exe使用详解(适用Linux)

    RAR 命令行语法: RAR.exe <命令> [ -<开关> ] <压缩文件> [ <@列表文件...> ] [ <文件...> ] [ ...

  8. java web spring异步方法

    在项目中,时常会有异步调用的需求 web.xml配置 <servlet> <description>spring mvc servlet</description> ...

  9. RHEL7.5 静默安装(silent mode)oracle11gr2数据库软件

    如果没有图形界面多可怕,或者图形界面安装总报些奇怪的错误多可怕,静默安装数据库软件了解一下 修改主机名.关闭selinux [root@localhost ~]$ sed -i '3,$d' /etc ...

  10. HTTPS中的加密验证部分理论

    为了加深自己对于https加密这一块的映象,决定写出来试试 就是在http层下面加了一个ssl层, 服务器将自己的公钥发送给证书机构,申请证书,证书机构首先会验证个服务器是否合法,线上或者线下,然后用 ...