zoukankan      html  css  js  c++  java
  • LeetCode491. 递增子序列

    题目

    给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。

    1. 给定数组的长度不会超过15。
    2. 数组中的整数范围是 [-100,100]。
    3. 给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。

    法一分析

    自己首先想法:本题和取子集的题目差不多,但不能通过排序+used数组来去重,因为是递增子序列,不可破坏原本子序列次序。我是通过把每次结果放到 set 里面来把结果进行去重。何时将结果加入 set ? 它和取子集问题一样,不必到叶子结点,每层都取,也就是进入下层后要将上层结果存入 set 中。最后再把set 中的结果放入 res中。

    法一代码

     1 class Solution {
     2 public:
     3     vector<int>path;
     4     vector<vector<int>>res;
     5     set<vector<int>>s;
     6     bool check(vector<int>nums){
     7         for(int i = 1;i < nums.size();i++){
     8             if(nums[i] < nums[i-1]) return false;
     9         }
    10         return true;
    11     }
    12     void backtracking(vector<int> nums,int startIndex){
    13         if(check(path) && path.size() >= 2){
    14             s.emplace(path);
    15             //res.push_back(path);
    16         }
    17             
    18         if(!check(path)) return;
    19 
    20         for(int i = startIndex;i < nums.size();i++){
    21             path.push_back(nums[i]);
    22             backtracking(nums,i+1);
    23             path.pop_back();
    24         }
    25     }
    26 
    27     vector<vector<int>> findSubsequences(vector<int>& nums) {
    28         backtracking(nums,0);
    29         for(auto it:s){
    30             res.push_back(it);
    31         }
    32         return res;
    33     }
    34 };

    上面set可使用unordered_set

    法二分析 按照Carl的思路

    直接排除可能重复的情形:只要同层重复使用元素,递增子序列就会重复注意要与 求子集问题(二)中去重区别。子集问题二是先排序然后看相邻元素是否重复使用。

    判断递增:如果选取的元素小于子序列里面最后一个元素,那么pass,着说明了不是递增。去重逻辑代码如下:

    if ((!path.empty() && nums[i] < path.back())
            || uset.find(nums[i]) != uset.end()) {
            continue;
    }

    注意 本题的数据范围为 [-100,100],数据范围小,可以直接用数组进行哈希,这样比set快。 

    法二代码

     1 class Solution {
     2 public:
     3     vector<int>path;
     4     vector<vector<int>>res;
     5     
     6     void backtracking(vector<int> nums,int startIndex){
     7         if(path.size() > 1) {
     8             res.push_back(path);
     9         }
    10         int used[201] = {0}; // 用数组来去重,数据范围是-100,100
    11 
    12         for(int i = startIndex;i < nums.size();i++){
    13             //非递增或者重复直接pass
    14             if((!path.empty() && path.back() > nums[i])
    15                 || used[100+nums[i]] == 1) continue;
    16             
    17             used[100+nums[i]] = 1; //表示这个元素使用过了
    18             path.push_back(nums[i]);
    19             backtracking(nums,i+1);
    20             path.pop_back();
    21             //注意不在这里恢复used数值,在下一层恢复used数值
    22         }
    23     }
    24 
    25     vector<vector<int>> findSubsequences(vector<int>& nums) {
    26         backtracking(nums,0);
    27         return res;
    28     }
    29 };

    注意上面代码,used数组恢复位置,本层不恢复。

  • 相关阅读:
    [c language] getopt
    编程经典问题
    一些常用的正则表达式
    [Head First Python]6. summary
    Java多线程
    JVM运行原理
    Struts2---自定义拦截器
    SpringMVC框架初步
    测试基本问题
    自动化测试
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14359018.html
Copyright © 2011-2022 走看看