题目描述:给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n^2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
子序列:它指的是在原有序列的基础上,删除0个或者多个数,其他数的顺序保持不变得到的结果。拿示例的这个序列来说:
[10,9,2,5,3,7,101,18]
随便拿掉0个数或多个数:比如说我去掉第一个数字10,去掉最后一个数18,但是不打乱这个序列的顺序,那么我得到的新的序列就是该序列的一个子序列:
[9,2,5,3,7,101]
啥是“上升”?这个就比较好理解了,它指的是排在后面的元素总是要大于排在前面的元素。
/*** @param {number[]} nums* @return {number}*/// 入参是一个数字序列const lengthOfLIS = function(nums) {// 缓存序列的长度const len = nums.length// 处理边界条件if(!len) {return 0}// 初始化数组里面每一个索引位的状态值const dp = (new Array(len)).fill(1)// 初始化最大上升子序列的长度为1let maxLen = 1// 从第2个元素开始,遍历整个数组for(let i=1;i<len;i++) {// 每遍历一个新元素,都要“回头看”,看看能不能延长原有的上升子序列for(let j=0;j<i;j++) {// 若遇到了一个比当前元素小的值,则意味着遇到了一个可以延长的上升子序列,故更新当前元素索引位对应的状态if(nums[j]<nums[i]) {dp[i] = Math.max(dp[i], dp[j] + 1)}}// 及时更新上升子序列长度的最大值if(dp[i] > maxLen) {maxLen = dp[i]}}// 遍历完毕,最后到手的就是最大上升子序列的长度return maxLen};
