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. 基于 IJKPlayer-concat 协议的视频无缝拼接技术实现

    一.前言 Hi,大家好,我是承香墨影! 开门见山,开篇名义.今天来聊聊如何将多段视频,拼接成一个完整而连续的视频,然后无缝进行播放. 这样的需求应该不算偏门吧? 最简单的就是一些视频 App,会将大段 ...

  2. DOM4j的修改删除方式

    ?xml version="1.0" encoding="UTF-8"?> <contactList> <contact id=&quo ...

  3. [BZOJ 4419][Shoi2013]发微博

    4419: [Shoi2013]发微博 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 665  Solved: 364[Submit][Status] ...

  4. C语言第四次作业-嵌套作业

    一.PTA实验作业 题目1:7-4 换硬币 1. 本题PTA提交列表 2.设计思路 第一:定义三个整型变量f,t,o,分别代表五分,两分,一分的数量 第二:输入待换金额x 第三:令f=x/5;t=x/ ...

  5. new malloc和delete free 的区别

    今天看了一个面试题:问new 和 malloc, delete 和 free 的区别,扭捏了半天,也没说完全:现总结如下: 1.先看看new 和 delete 看一个例子: <span styl ...

  6. 14-TypeScript简单工厂模式

    在TypeScript中,要调用功能,通常在调用方通过实例化被调用方对象来调用相关方法,但这种实现在调用方和被调用方形成了强耦合的关系. 另外如果被调用方有种实现,在调用方需要根据场景去实例化不同的类 ...

  7. Session 和 Cookie 区别

    会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.==Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用 ...

  8. 看漫画学Flux

    原文地址:A cartoon guide to Flux - by Lin Clark Flux在目前web开发中最受欢迎也较不被人理解,本文会以简单易懂的方式解释它. 出现问题 首先,我要声明Flu ...

  9. 3-51单片机WIFI学习(开发板8266底层源码介绍)

    上一篇链接  http://www.cnblogs.com/yangfengwu/p/8743502.html 直接上源码:注意源码有两部分,第一部分是一开始的时候写在模块内部的,另一部分是存在手机内 ...

  10. Python内置函数(39)——help

    英文文档: help([object]) Invoke the built-in help system. (This function is intended for interactive use ...