子序列问题
点赞👍👍收藏🌟🌟关注💖💖
你的支持是对我最大的鼓励,我们一起努力吧!😃😃
1.最长递增子序列
题目链接: 300. 最长递增子序列
题目分析:
什么是子序列?
子序列可以是数组中不连续的部分也可以是连续的部分,但是选择的数必须和原数组保持相对顺序不变。
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度,严格递增就是一直往上,没有水平。
算法原理:
1.状态表示
经验 + 题目要求
以 i 位置为结尾,巴拉巴拉
题目要求找到其中最长严格递增子序列的长度,首先 以 i 位置元素为结尾要是子序列,子序列还要是严格递增,并且还是最长。因此
dp[i] 表示:以 i 位置元素为结尾的所有子序列中,最长递增子序列的长度
2.状态转移方程
dp[i] 表示:以 i 位置元素为结尾的所有子序列中,最长递增子序列的长度,可以先想一下,以 i 位置元素为结尾的所有子序列可以分几类:
一是,i 位置元素本身就是子序列
二是,i 位置元素跟在前面位置元素( 0 <= j <= i - 1)的后面构成子序列
因此状态转移方程可以分成两类情况讨论
长度为1,递增子序列的长度就是1
长度大于1,在 0 <= j <= i -1 区间, 要的是严格递增的子序列,因此必须要满足 nums[j] < nums[i] 前提下,我们要的是最长递增子序列,那 j 位置本身要是一个最长递增子序列,而dp[j] 表示:以 j 位置元素为结尾的所有子序列中,最长递增子序列的长度,在加上 i 位置就行了,注意 j 是变化的,我们要的是0 <= j <= i -1 区间内最长的递增子序列。因此我们要的是这个区间最大的 dp[j] +1
3.初始化
表里面的所有值初始为1,正好长度为1的不用去管了。
4.填表顺序
从左往右
5.返回值
dp[i] 表示:以 i 位置元素为结尾的所有子序列中,最长递增子序列的长度。因此返回的是dp表中的最大值
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
// 1.创建 dp 表
// 2.初始化
// 3.填表
// 4.返回值
int n = nums.size();
vector<int> dp(n, 1);
int ret = 1;
for(int i = 1; i < n; ++i)
{
for(int j = i - 1; j >= 0; --j)
{
if(nums[j] < nums[i])
{
dp[i] = max(dp[i], dp[j] + 1);
}
ret = max(ret, dp[i])