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] Increasing Subsequences 递增子序列的更多相关文章

  1. [LeetCode] 491. Increasing Subsequences 递增子序列

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

  2. 491 Increasing Subsequences 递增子序列

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

  3. 子序列 sub sequence问题,例:最长公共子序列,[LeetCode] Distinct Subsequences(求子序列个数)

    引言 子序列和子字符串或者连续子集的不同之处在于,子序列不需要是原序列上连续的值. 对于子序列的题目,大多数需要用到DP的思想,因此,状态转移是关键. 这里摘录两个常见子序列问题及其解法. 例题1, ...

  4. leetcode最长递增子序列问题

    题目描写叙述: 给定一个数组,删除最少的元素,保证剩下的元素是递增有序的. 分析: 题目的意思是删除最少的元素.保证剩下的元素是递增有序的,事实上换一种方式想,就是寻找最长的递增有序序列.解法有非常多 ...

  5. [Leetcode] distinct subsequences 不同子序列

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  6. Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences)

    Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences) 深度优先搜索的解题详细介绍,点击 给定一个整型数组, 你的任务是找到所有该数组 ...

  7. [Swift]LeetCode491. 递增子序列 | Increasing Subsequences

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

  8. [LeetCode] Increasing Triplet Subsequence 递增的三元子序列

    Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...

  9. Longest Increasing Subsequences(最长递增子序列)的两种DP实现

    一.本文内容 最长递增子序列的两种动态规划算法实现,O(n^2)及O(nlogn).     二.问题描述 最长递增子序列:给定一个序列,从该序列找出最长的 升序/递增 子序列. 特点:1.子序列不要 ...

随机推荐

  1. CentOS7搭建solr7.2

    solr介绍 一.Solr它是一种开放源码的.基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中. 二.Solr 提供了层面搜索(就是统计).命中醒目显示并且支持多种输出格式( ...

  2. drbd(二):配置和使用

    本文目录:1.drbd配置文件2.创建metadata区并计算metadata区的大小3.启动drbd4.实现drbd主从同步5.数据同步和主从角色切换6.drbd脑裂后的解决办法7.drbd多卷组配 ...

  3. 每日冲刺报告——Day5(Java-Team)

    第五天报告(11.6  周一) 团队:Java-Team 成员: 章辉宇(284) 吴政楠(286) 陈阳(PM:288) 韩华颂(142) 胡志权(143) github地址:https://git ...

  4. electron-vue工程创建

    没有vue创建经验请移步至 vue下载与安装 使用vue创建electron-vue工程 vue init simulatedgreg/electron-vue my-project 安装elemen ...

  5. python 单向链表实现

    单链表的操作 is_empty() 链表是否为空 length() 链表长度 travel() 遍历整个链表 add(item) 链表头部添加元素 append(item) 链表尾部添加元素 inse ...

  6. 从PRISM开始学WPF(二)Prism?

    目录: 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Modu ...

  7. wpf研究之道——datagrid控件数据绑定

    前台: <DataGrid x:Name="TestCaseDataGrid" ItemsSource="{Binding}" > {binding ...

  8. nyoj 背包问题

    背包问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w< ...

  9. zookeeper安装及环境变量设置

    下载 首先去官网下载(自行选择版本):http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.11/然后执行tar -zxvf解压 对于后台安装 ...

  10. STM32F4系列单片机上使用CUBE配置MBEDTLS实现pem格式公钥导入

    |版权声明:本文为博主原创文章,未经博主允许不得转载. 最近尝试在STM32F4下用MBEDTLS实现了公钥导入(我使用的是ECC加密),整个过程使用起来比较简单. 首先,STM32F4系列CUBE里 ...