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;
        
    }
};

参考 :

posted @ 2021-03-10 11:09  boyang987  阅读(74)  评论(0编辑  收藏  举报