最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

/**
 * 最长递增子序
 * 很具小巧思。新建数组 cell,用于保存最长上升子序列。
 * 对原序列进行遍历,将每位元素二分插入 cell 中。
 * 如果 cell 中元素都比它小,将它插到最后
 * 否则,用它覆盖掉比它大的元素中最小的那个。
 * 总之,思想就是让 cell 中存储比较小的元素。这样,cell 未必是真实的最长上升子序列,但长度是对的。
 */
const lengthOfLIS = (nums = [0, 1, 0, 3, 2, 3]) => {
    const len = nums.length
    if (len <= 1) return len
    const cell = [nums[0]]
    for (let i = 1; i < len; i++) {
        const num = nums[i];
        if (cell[cell.length - 1] < num) {
            cell.push(num)
            continue
        }
        let startIdx = 0,
            endIdx = cell.length - 1
        while (startIdx < endIdx) {
            const midIdx = Math.floor((startIdx + endIdx) / 2)
            if (cell[midIdx] < num) {
                startIdx = midIdx + 1
            } else {
                endIdx = midIdx
            }
        }
        cell[startIdx] = num
    }
    return cell.length
};

  双层循环

/**
 * @param {number[]} nums
 * @return {number}
 */
const lengthOfLIS = (nums) => {
    const len = nums.length
    if (len <= 1) return len
    const stack = [nums[0]]
    for (let i = 0; i < nums.length; i++) {
        const v = nums[i]
        if (v > stack[stack.length - 1]) {
            stack.push(v)
        } else {
            for (let j = 0; j < stack.length; j++) {
                const jv = stack[j]
                if (jv >= v) {
                    stack[j] = v
                    break
                }
            }
        }
    }
    return stack.length
};

 

posted @ 2023-02-17 00:29  671_MrSix  阅读(32)  评论(0)    收藏  举报