不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。喜欢的事自然可以坚持,不喜欢的怎么也长久不了。
LeetCode:原题地址
题目要求
给你一个整数数组 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 。
示例 2:
输入: nums = [0,1,0,3,2,3]
输出: 4
示例 3:
输入: nums = [7,7,7,7,7,7,7]
输出: 1
思路
准备tail数组存放最长上升子序列,核心思想就是越小的数字越要往前放,这样后面就会有更多的数字可以加入tails数组。将nums中的数不断加入tail,当nums中的元素比tail中的最后一个大时 可以放心push进tail,否则进行二分查找,让比较小的数二分查找到合适的位置,让后面有更多的数字与这个数形成上升子序列
/**
* @param {number[]} nums
* @return {number}
*/
var lengthOfLIS = function (nums) {
let n = nums.length;
if (n <= 1) {
return n;
}
let tail = [nums[0]];//存放最长上升子序列数组
for (let i = 0; i < n; i++) {
if (nums[i] > tail[tail.length - 1]) {//当nums中的元素比tail中的最后一个大时 可以放心push进tail
tail.push(nums[i]);
} else {//否则进行二分查找
let left = 0;
let right = tail.length - 1;
while (left < right) {
let mid = (left + right) >> 1;
if (tail[mid] < nums[i]) {
left = mid + 1;
} else {
right = mid;
}
}
tail[left] = nums[i];//将nums[i]放置到合适的位置,此时前面的元素都比nums[i]小
}
}
return tail.length;
};