LeetCode 300. 最长递增子序列

LeetCode 300. 最长递增子序列

在这里插入图片描述

这道题可以说多次出现在了我的刷题生涯当中。依据我的个人经验,从本科的时候备战蓝桥杯、备战天梯赛,到如今刷 LeetCode 准备面试,最长递增子序列一定是 DP 当中绕不开的一道题。

我发现这道题尽管做过很多次,甚至整理过很多次,但是每一次重新打开这道题目的时候,都需要再看一遍上次解题的思路才能顺利做出来,看一眼之前的代码片便恍然大悟,遂通过本文对这道题目的所用到的 DP 思想进行详细的整理。

题目描述

题目描述不需要过多赘述了,一个简单的例子是:

1 0 2 0 3 0 108 9

这个序列的最长递增子序列的长度是4,可能的最长递增子序列包括[1, 2, 3, 108][1, 2, 3, 9]

思路

使用 DP 来解决这个问题。

具体来说,需要开一个一维数组,数组当中每个位置的值,也就是 DP 每一位的状态,表示的就是到这个数位为止最长递增子序列的长度。

那么我们应该如何维护这个状态呢?

其实很简单,比如对于 1 0 2 0 3 0 108 9 这个例子,当我们维护到 108 这个数对应位置的状态时,直接从头开始遍历数组直到这个位置,假设当前这个位置的下标为 i,使用 j 表示遍历数组的移动下标,那么当前位置的 DP 数组状态为 dp[i] = max(dp[i], dp[j] + 1)。原因是当前位置的最长递增子序列的长度要么是自己本身,要么是前面那个比当前位置更小的数加上一。

最后找到 DP 数组当中的最大元素就是最终的答案。

C++ 代码

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp(n, 0);

        for(int i=0; i<n; i++) {
            dp[i] = 1;
            for(int j=0; j<i; j++) {
                if(nums[j] < nums[i]) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
        }

        return *max_element(dp.begin(), dp.end());
    } 
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值