题目描述:给定一个无序的整数数组,找到其中最长上升子序列的长度。

    示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

    说明: 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 你算法的时间复杂度应该为 O(n^2) 。

    进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

    子序列:它指的是在原有序列的基础上,删除0个或者多个数,其他数的顺序保持不变得到的结果。拿示例的这个序列来说:

    1. [10,9,2,5,3,7,101,18]

    随便拿掉0个数或多个数:比如说我去掉第一个数字10,去掉最后一个数18,但是不打乱这个序列的顺序,那么我得到的新的序列就是该序列的一个子序列:

    1. [9,2,5,3,7,101]

    啥是“上升”?这个就比较好理解了,它指的是排在后面的元素总是要大于排在前面的元素。

    1. /**
    2. * @param {number[]} nums
    3. * @return {number}
    4. */
    5. // 入参是一个数字序列
    6. const lengthOfLIS = function(nums) {
    7. // 缓存序列的长度
    8. const len = nums.length
    9. // 处理边界条件
    10. if(!len) {
    11. return 0
    12. }
    13. // 初始化数组里面每一个索引位的状态值
    14. const dp = (new Array(len)).fill(1)
    15. // 初始化最大上升子序列的长度为1
    16. let maxLen = 1
    17. // 从第2个元素开始,遍历整个数组
    18. for(let i=1;i<len;i++) {
    19. // 每遍历一个新元素,都要“回头看”,看看能不能延长原有的上升子序列
    20. for(let j=0;j<i;j++) {
    21. // 若遇到了一个比当前元素小的值,则意味着遇到了一个可以延长的上升子序列,故更新当前元素索引位对应的状态
    22. if(nums[j]<nums[i]) {
    23. dp[i] = Math.max(dp[i], dp[j] + 1)
    24. }
    25. }
    26. // 及时更新上升子序列长度的最大值
    27. if(dp[i] > maxLen) {
    28. maxLen = dp[i]
    29. }
    30. }
    31. // 遍历完毕,最后到手的就是最大上升子序列的长度
    32. return maxLen
    33. };