代码随想录第二十九天 | 491.递增子序列

134 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

491.递增子序列

题目描述

题目给出一个整型数组,要求找到所有该数组的递增子序列。限制条件是递增子序列的长度至少是2。

解题

递增子序列,类似于取有序的子集,并且要求不能有相同的递增子序列。很容易让我们联想到子集那一道题,所以我们仍然使用回溯的方法解决。

仍然是回溯三部曲:

  1. 递归函数的参数

回溯的参数仍然是横向for循环的起始位置。

  1. 回溯函数终止条件

for循环结束后,自然会得到一个结果。但是本题要求递增子序列的长度至少为2,所以需要对数组的长度有限制。

  1. 单层搜索的过程

从下图我们可以看到同一层可能会出现重复的递增子序列。所以在搜索的过程中,我们需要判断当前遍历的元素与上一个元素是否相同。另外需要判断当前是否为递增子序列。

回溯的过程如下图所示:

image.png

我们可以看出三种不符合的情况,第1个是数组的长度小于2,第2个是单层出现了重复的递增子序列,第3个是子序列但并不是递增的。

代码如下:

var findSubsequences = function(nums) {
    let result = [],path = []
    function backstracing(startIndex) {
        if(path.length > 1) result.push(path.slice())
        let uset = []
        for(let i = startIndex;i < nums.length;i++) {
            if(path.length > 0 && nums[i] < path[path.length - 1] || uset[nums[i] + 100])  continue
            uset[nums[i] + 100] = true
            path.push(nums[i])
            backstracing(i + 1)
            path.pop()
        }
    }
    backstracing(0)
    return result
};

需要注意的是要将path pushresult时,我们通过slice复制了一份path放入result中。

之前在看题解的时候看到题解中将uset[nums[i] + 100] 不理解为什么要加100,后来看到题目中-100 <= nums[i] <= 100才明白。不过leetcode的测试用例中不会出错。