leetcode300.最长递增子序列

leetcode300.最长递增子序列

题目

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

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

用例

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
输入:nums = [0,1,0,3,2,3]
输出:4
输入:nums = [7,7,7,7,7,7,7]
输出:1

求解

/**
 * @param {number[]} nums
 * @return {number}
 */
var lengthOfLIS = function(nums) {
    //动态规划时间复杂度为O(n2)
    // let res =1
    // let arr = new Array(nums.length).fill(1)
    // for(let i=1;i<nums.length;i++){
    //     let max_len =0
    //     for(let j=0;j<i;j++){
    //         if(nums[j]<nums[i]){
    //             max_len=Math.max(max_len,arr[j])
    //         }
    //         arr[i]=max_len+1
    //         res = Math.max(arr[i],res)
    //     }
    // }
    // return res
    let heap_min = []
    heap_min[0]=nums[0]
    for(let i=1;i<nums.length;i++){
        //进行二分查询寻找比它大的第一个位置
        let index = fn(nums[i])
        if(heap_min[index]<nums[i]){
            heap_min[heap_min.length]=nums[i]
        }else{
            heap_min[index]=nums[i]
        }
    }
    return heap_min.length

    function fn(num){
        let start = 0
        let last = heap_min.length-1
        while(start<last){
            let mid = Math.floor((last+start)/2)
            if(heap_min[mid]>=num){
                last=mid
            }else{
                start=mid+1
            }
        }
        return start
        
    }
};
posted @ 2021-12-26 15:02  BONiii  阅读(23)  评论(0)    收藏  举报