题解 | #最长上升子序列(一)#

最长上升子序列(一)

https://www.nowcoder.com/practice/5164f38b67f846fb8699e9352695cd2f

如何体现上升的逻辑?

定义DP数组存放的是以当前位置i结尾的子序列中的最长上升子序列长度,此时可以在0到i的所有子数组中寻找上升子序列,因为是0到i的子数组,所以保证了j<i,所以当arr[j]<arr[i]时,说明i是上升子序列的一部分,则此时以arr[i]结尾的上升子序列长度为dp[i]=1+dp[j]。

如何思考状态转移方程?

在0到i的子数组中,遍历每个子数组时都更新dp[i]为当前子数组中以arr[i]结尾的最大子序列长度,dp[i] = max(dp[i], dp[j]+1)

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 给定数组的最长严格上升子序列的长度。
 * @param arr int整型一维数组 给定的数组
 * @return int整型
 */
function LIS( arr ) {
    // write code here
    const dp = new Array(arr.length).fill(1);  // 存放以每个位置结尾的子序列中的最长上升子序列长度,因为数组中至少有一个元素,而且要更新最大值,因此初始值设置为最小值1

    for (let i = 0; i < arr.length; ++i) {
        for (let j = 0; j < i; ++j) {  // 求从0到i的子数组中的最长上升子序列长度
            if (arr[j] <= arr[i]) {  // 体现上升逻辑,arr[i]是子序列的末尾,且arr[j] < arr[i]说明是上升的,此时更新dp[i]即以arr[i]为上升子序列末尾的最大长度
                dp[i] = Math.max(dp[j]+1, dp[i]);
            }
        }
    }

    return arr.length === 0? 0 : Math.max(...dp);  // 找到所有位置为上升子序列末尾时的最长子序列长度,注意可能有空数组的情况
}
console.log(LIS([6,3,1,5,2,3,7]))
module.exports = {
    LIS : LIS
};

全部评论

相关推荐

尊嘟假嘟点击就送:加v细说,问题很大
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务