持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 6 天,点击查看活动详情
题目链接
题目描述
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
测试用例
用例1:
输入: nums = [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长递增子序列是 [2,3,7,101],因此长度为 4 。
限制
1 <= nums.length <= 2500-104 <= nums[i] <= 10^4
题目分析
题目给定一个字符串,需要我们求这个字符串中,递增且最长的子字符串。其中,子字符串可以不一定是连续的。以 [10,9,2,5,3,7,101,18] 为例,我们依次挑出 2,3,7,101 构成一个符合要求的子字符串,同时是最长的子字符串,长度为 4
如果尝试构建以个最长的子字符串,由于不限定必须连续,无从下手
换一种思路,维护另一个数组 arr,用于标记指定下标元素 nums[i],他能构造的最长的字符串的长度,那么 nums[i+1] 能构造的最长子字符串的长度,就是 nums 中 j = [0, i+1] 下标中符合要求的元素在 arr 中对应下标的最大值 +1,这里的符合要求的元素定义为 nums[i+1] > nums[j]
以用例推导的数据如下:
| index(下标) | nums[index] | arr[index] | 上一个最长元素长度 |
|---|---|---|---|
| 0 | 10 | 1 | 无 |
| 1 | 9 | 1 | 无 |
| 2 | 2 | 1 | 无 |
| 3 | 5 | 2 | nums[2] |
| 4 | 3 | 2 | nums[2] |
| 5 | 7 | 3 | nums[3] 或 nums[4] |
| 6 | 101 | 4 | nums[5] |
| 7 | 18 | 4 | nums[5] |
代码实现
完整的代码实现如下
var lengthOfLIS = function (nums) {
let arr = new Array(nums.length).fill(0);
let result = 0;
for (let i = 0; i < nums.length; i++) {
const n1 = nums[i];
let max = 0;
for (let j = 0; j < i; j++) {
const n2 = nums[j];
if (n1 > n2) {
max = Math.max(max, arr[j]);
}
}
arr[i] = max + 1;
result = Math.max(result,arr[i])
}
return result;
};