• 491. 递增子序列


    491. 递增子序列

    题目链接: 491. 递增子序列(中等)

    给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

    数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

    示例 1:

    输入:nums = [4,6,7,7]
    输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]

    示例 2:

    输入:nums = [4,4,3,2,1]
    输出:[[4,4]]

    提示:

    • 1 <= nums.length <= 15

    • -100 <= nums[i] <= 100

    解题思路

    这道题咋一看挺像90. 子集 II的,所以需要注意两题的区别。90. 子集 II是通过排序来进行去重。但本题不能通过排序来进行去重,因为一旦使用排序,那排序完的得到所有子集都将是递增的,不符合题意(别被第一个示例带偏了)。本题的去重操作可以有两种方法来实现,一是使用unordered_set<int>来记录本层的元素是否重复使用,二是用 数组 记录本层的元素是否重复使用。不过对unordered_set<int> 进行频繁的插入,判断等操作是很费时的。

    C++

    class Solution {
    public:
        vector<int> path;
        vector<vector<int>> result;
    ​
        void backTracking(vector<int> nums, int start) {
            if (path.size() > 1) {
                // 判断当前序列是否递增(只需判断最后两个数的大小就好,前面的已经判断过)
                if (path[path.size() - 1] >= path[path.size() - 2]) {
                    result.push_back(path);
                } else {
                    return;
                }
            }
    ​
            // 对本层元素进行去重(这里使用了集合来实现,还可以用数组来实现(效率更高))
            // visited是记录本层元素是否重复使用,新的一层visited都会重新定义(清空),所以要知道visited只负责本层
            unordered_set<int> visited;
            for (int i = start; i < nums.size(); i++) {
                // 判断当前元素在本层是否已经使用过
                // 使用过
                if (visited.find(nums[i]) != visited.end()) {
                    continue;
                }
                // 没使用过
                visited.insert(nums[i]); // 使用该元素,并记录下来,本层的后面不能再用了
                path.push_back(nums[i]);
                backTracking(nums, i + 1);
                path.pop_back();
            }
        }
    ​
        vector<vector<int>> findSubsequences(vector<int>& nums) {
            path.clear();
            result.clear();
            backTracking(nums, 0);
            return result;
        }
    };
    class Solution {
    public:
        vector<int> path;
        vector<vector<int>> result;
    ​
        void backTracking(vector<int> nums, int start) {
            if (path.size() > 1) {
                    result.push_back(path);
            }
    ​
            // 用数组来实现去重(效率更高)
            // 题目中说数值范围是[-100,100]
            int visited[201] = {0};
            for (int i = start; i < nums.size(); i++) {
                // 判断当前元素在本层是否已经使用过
                // 使用过,+100是为了将[-100,0]中的值变为正数
                if (visited[nums[i] + 100] == 1) {
                    continue;
                }
                // 保证得到的序列是递增序列
                if (path.size() > 0 && nums[i] < path[path.size() - 1]) {
                    continue;
                }
                // 没使用过
                visited[nums[i] + 100] = 1; // 使用该元素,并记录下来,本层的后面不能再用了
                path.push_back(nums[i]);
                backTracking(nums, i + 1);
                path.pop_back();
            }
        }
    ​
        vector<vector<int>> findSubsequences(vector<int>& nums) {
            path.clear();
            result.clear();
            backTracking(nums, 0);
            return result;
        }
    };

    JavaScript

    let path = [];
    let result = [];
    ​
    const backTracking = (nums, start) => {
        if (path.length > 1) {
            result.push([...path]);
        }
    ​
        let visited = new Array(201);
        for (let i = start; i < nums.length; i++) {
            if (visited[nums[i] + 100] === 1) {
                continue;
            }
            if (path.length > 0 && nums[i] < path[path.length - 1]) {
                continue;
            }
            visited[nums[i] + 100] = 1;
            path.push(nums[i]);
            backTracking(nums, i + 1);
            path.pop();
        }
    }
    ​
    var findSubsequences = function(nums) {
        path = [];
        result = [];
        backTracking(nums, 0);
        return result;
    };

     

     

     

  • 相关阅读:
    描述一下 JVM 加载 class 文件的原理机制?
    Java 中会存在内存泄漏吗,请简单描述
    关于同步机制的一些见解
    Mybatis 一对一,一对多,多对一,多对多的理解
    关于JavaBean实现Serializable接口的见解
    Python 文件I/O
    Python 模块
    Python 函数
    Python time tzset()方法
    Python time time()方法
  • 原文地址:https://www.cnblogs.com/wltree/p/15739680.html
Copyright © 2020-2023  润新知