increasing subsequences (递增子序列)

1人阅读 评论(0) 收藏 举报
分类:

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.

 https://www.cnblogs.com/grandyang/p/6388103.html

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

vector<vector<int>> findSubsequences(vector<int>& nums) {
        set<vector<int>> res;
        vector<int> out;
        helper(nums, 0, 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() >= 2) 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 + 1, out, res);
            out.pop_back();
        }
    }

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

 

vector<vector<int>> findSubsequences(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> out;
        helper(nums, 0, out, res);
        return res;
    }
    void helper(vector<int>& nums, int start, vector<int>& out, vector<vector<int>>& res) {
        if (out.size() >= 2) 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 + 1, out, res);
            out.pop_back();
        }
    }

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

vector<vector<int>> findSubsequences(vector<int>& nums) {
        set<vector<int>> res;
        vector<vector<int>> cur(1);
        for (int i = 0; i < nums.size(); ++i) {
            int n = cur.size();
            for (int j = 0; 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() >= 2) res.insert(cur.back());
            }
        }
        return vector<vector<int>>(res.begin(), res.end());
    }

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

vector<vector<int>> findSubsequences(vector<int>& nums) {
        vector<vector<int>> res, cur(1);
        unordered_map<int, int> m;
        for (int i = 0; i < nums.size(); ++i) {
            int n = cur.size();
            int 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() >= 2) res.push_back(cur.back());
            }
        }
        return res;
    }

查看评论

[leetcode] 491. Increasing Subsequences

Given an integer array, your task is to find all the different possible increasing subsequences of t...
  • juanqinyang
  • juanqinyang
  • 2017-03-19 17:22:14
  • 784

【LeetCode】 491. Increasing Subsequences

Given an integer array, your task is to find all the different possible increasing subsequences of t...
  • qq_31129455
  • qq_31129455
  • 2017-01-23 09:25:02
  • 1312

491. Increasing Subsequences**

Given an integer array, your task is to find all the different possible increasing subsequences of t...
  • alwaystry
  • alwaystry
  • 2017-01-23 18:23:53
  • 523

leetcode-491. Increasing Subsequences

考察点:dfs; 思路:dfs,对于dfs函数,其中对每一个位置的数都选择选或者不选来判断。最后,用set,将set转化为vector的函数是copy(iter1, iter2, back_inse...
  • u014257954
  • u014257954
  • 2017-05-12 10:39:55
  • 108

Increasing Subsequences

一. Increasing SubsequencesGiven an integer array, your task is to find all the different possible in...
  • u014652699
  • u014652699
  • 2017-03-15 23:39:14
  • 97

最长递增子序列O(NlogN)算法(leetcode 300. Longest Increasing Subsequence )

最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS。 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了。 假设存在一个序列d[1....
  • jiary5201314
  • jiary5201314
  • 2016-04-16 21:06:45
  • 3077

动态规划之最长递增子序列(Longest Increasing Subsequence)

原文地址:http://www.geeksforgeeks.org/dynamic-programming-set-3-longest-increasing-subsequence/ We have...
  • sinat_36246371
  • sinat_36246371
  • 2016-10-13 12:12:37
  • 1133

Leetcode 491. Increasing Subsequences 上升序列 解题报告

1 解题思想hi,好久不见,最近有点忙,更新的很慢。 这道题是给了一个已经排好序的数组,让你找出所有的子序列,这些子序列要求同样是不下降的(就是i+1的数肯定大于等于i),相同的序列不能重复出现,但...
  • MebiuW
  • MebiuW
  • 2017-02-26 16:15:02
  • 722

【Leetcode】491. Increasing Subsequences

题目:https://leetcode.com/problems/increasing-subsequences/?tab=Description 找出所有的长度大于等于2的递增序列。 思路:这里...
  • u010900754
  • u010900754
  • 2017-03-11 05:43:22
  • 182

1085 - All Possible Increasing Subsequences[树状数组]

1085 - All Possible Increasing Subsequences PDF (English) Statistics Forum ...
  • llkpersonal
  • llkpersonal
  • 2014-09-01 22:23:33
  • 308
    个人资料
    持之以恒
    等级:
    访问量: 9万+
    积分: 2510
    排名: 1万+
    最新评论