LeetCode 300. 最长递增子序列 子序列问题 动态规划
题目描述
给你一个整数数组 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 。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
动态规划
- 子序列问题
- 设DP[i] 为 考虑到 index=i时候 最长递增子序列长度 ,一定以nums[i]为结尾
- 初始化 DP[0] =1
- 转移方程 DP[i] = max(dp[0:i] ) +1 when nums[i]> nums[j]
代码
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
//子序列问题
// 设DP[i] 为 考虑到 index=i时候 最长递增子序列长度
// DP[i] = max(dp[0:i] ) +1 when nums[i]> nums[j]
// 初始化 DP[0] =1
//原理验证
// e.g 0,1,0,3,2,3
// dp: 1 2 2 3 3 4
// 报错 每次 dp[i] = tmax+1
// e.g [10,9,2,5,3,7,101,18]
// dp:1 1 1 2 2 3 4 4
// 报错 并不是 最后的DP是最优结果
// e.g [1,3,6,7,9,4,10,5,6]
// err dp:1 2 3 4 5 5? 6 6 7?
// dp: 1 2 3 4 5 3 6 4 5
std::vector<int> dp(nums.size(), 1);
for(int i=1;i<nums.size();i++)
{
int tmax=0;
for(int j=0;j<i;j++)
if(nums[i]> nums[j] && dp[j] > tmax)
{
//是否有更新
tmax= dp[j];
}
if(tmax) dp[i] = tmax+1 ;
}
// 按照卡丹算法思路 应该求DP最大元素
for(auto x: dp) std::cout << x << " ";
auto itor= std::max_element(dp.begin(),dp.end());
return *itor;
}
};