lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 题目

 

 

 

读题 

考查点

 

这道题的考查点是:

  • 如何定义合适的状态,即dp[i]的含义。
  • 如何找到状态转移方程,即dp[i]和dp[j]的关系。
  • 如何初始化和更新状态,即dp[i]的初始值和最大值。
  • 如何从状态数组中得到最终结果,即res的值。

2. 解法

思路

讲一下思路吧。

这个问题的核心是找到数组中的最长递增子序列,也就是说,找到一个子序列,使得它的元素从左到右递增,并且长度最大。

我们可以用动态规划的方法来解决这个问题,动态规划的思想是把一个大问题分解成若干个小问题,并且利用已经解决的小问题的结果来解决大问题。

具体来说,我们可以定义一个状态dp[i],表示以nums[i]为结尾的最长递增子序列的长度。也就是说,如果我们知道了dp[i]的值,那么我们就知道了以nums[i]结尾的最长递增子序列是什么。

那么,如何求解dp[i]呢?我们可以从前往后遍历数组,对于每个元素nums[i],我们可以遍历它之前的所有元素nums[j],如果nums[j] < nums[i],那么说明nums[j]和nums[i]可以构成一个递增子序列,而且这个递增子序列的长度就是dp[j] + 1。所以,我们可以用dp[j] + 1来更新dp[i],取最大值。这样,我们就得到了以nums[i]为结尾的最长递增子序列的长度。

最后,我们只需要遍历一遍dp数组,找到其中的最大值,就是整个数组的最长递增子序列的长度了。

 

这道题的状态转移公式是:

dp[i]=0j<i and nums[j]<nums[i]max(dp[j]+1)

也就是说,dp[i]等于在所有满足nums[j] < nums[i]的j中,找到最大的dp[j] + 1。

这个公式的意义是,对于每个元素nums[i],我们要找到它之前的所有比它小的元素nums[j],并且找到这些元素中最长递增子序列的长度dp[j],然后加上1,就是以nums[i]为结尾的最长递增子序列的长度了。

 

代码逻辑

 

代码的逻辑如下:

  • 首先,创建一个dp数组,dp[i]表示以nums[i]为结尾的最长递增子序列的长度。
  • 然后,初始化dp数组,每个元素最小都为1,因为每个元素自己就是一个长度为1的递增子序列。
  • 接着,创建一个变量res,用来记录最终的结果,初始值为0。
  • 然后,遍历数组,从第二个元素开始,对于每个元素nums[i],我们可以遍历它之前的所有元素nums[j],如果nums[j] < nums[i],那么说明nums[j]和nums[i]可以构成一个递增子序列,而且这个递增子序列的长度就是dp[j] + 1。所以,我们可以用dp[j] + 1来更新dp[i],取最大值。这样,我们就得到了以nums[i]为结尾的最长递增子序列的长度。
  • 最后,遍历一遍dp数组,找到其中的最大值,赋给res,就是整个数组的最长递增子序列的长度了。

具体实现

class Solution {
    public int lengthOfLIS(int[] nums) {
        // 创建一个dp数组,dp[i]表示以nums[i]为结尾的最长递增子序列的长度
        int[] dp = new int[nums.length];
        // 初始化dp数组,每个元素最小都为1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1;
        }
        // 创建一个变量res,用来记录最终的结果
        int res = 0;
        // 遍历数组,从第二个元素开始
        for (int i = 1; i < nums.length; i++) {
            // 遍历当前元素之前的所有元素
            for (int j = 0; j < i; j++) {
                // 如果当前元素大于之前的元素,说明可以构成递增子序列
                if (nums[i] > nums[j]) {
                    // 更新dp[i],取最大值
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            // 更新res,取最大值
            res = Math.max(res, dp[i]);
        }
        // 返回结果
        return res;
    }
}

  

3. 总结

posted on 2023-05-01 16:46  白露~  阅读(22)  评论(0编辑  收藏  举报