🌈【LeetCode.最长递增子序列】- JavaScript =>DP+二分

883 阅读2分钟

「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


题意描述

给你一个整数数组 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

分析

这应该是非常非常经典的题型了吧,这类题型一般有两种做法,一种是DP也就是动态规划,另一种做法就是二分查找法。

解法一:DP

思路:我们去维护一个额外的数组,该数组存放最长递增序列,如果要插入的数据无法构成最大递增子序列,所以不能插入,但后面可能有更长的序列,所以在保持原数组仍为最大递增序列的情况下把4放进去,也就是把3更新为4,为后面可能出现的最大递增序列做准备。

var lengthOfLIS = function(nums) {
    const dp = new Array(nums.length)
    dp[0] = 1

    // 步骤1:计算dp[i]的对应长度
    for(let i = 1; i < dp.length; i++) {
        // 寻找前面小于nums[i]的最大dp值
        let j = 0
        let belowMaxDP = 0
        while (j < i) {
            if (nums[j] < nums[i] && dp[j] > belowMaxDP) {
                belowMaxDP = dp[j]
            }
            j++
        }
        dp[i] = belowMaxDP + 1
    }
    let max = 1
    let i = 0
    while (i < dp.length) {
        if (dp[i] > max) {
            max = dp[i]
        }
        i++
    }
    return max
};

解法2:DP+二分

思路:在之前的思路上加上二分,提高效率。

var lengthOfLIS = function(nums) {
    const dp = new Array(nums.length).fill(0)
    let len = 0
    for(let i = 0;i < nums.length;i++) {
        let ind = binarySearch(dp, 0, len, nums[i])
        if(ind < 0) ind = -ind
        dp[ind] = nums[i]
        if(ind === len) len++
    }
    return len
};

function binarySearch(arr, from ,to, target){
    if(to === 0) return -0
    if(target < arr[from]) return -from
    if(target > arr[to - 1]) return -to
    let l = from
    let r = to
    while(l < r) {
        const mid = Math.floor((l + r) / 2)
        if(target > arr[mid]) {
            l = mid + 1
        } else if(target < arr[mid]) {
            r = mid
        } else {
            l = mid
            r = mid
        }
    }
    return arr[l] === target ? l : -l
}

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤