补|(52/60)最长递增子序列、最长连续递增序列、最长重复子数组

子序列问题

最长递增子序列

leetcode:300. 最长递增子序列

动态规划

代码实现

/*
以nums[i]结尾的(含)递增子序列最长为dp[i]

dp[i]由dp[0~i-1]的最大值推出
if(nums[i] > nums[j]) dp[i] = max(dp[i],dp[j] + 1);    // 如果严格递增

dp[0] = 1;其余为0

正序遍历
*/

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> dp(nums.size(),1);
        int maxIndex = 0;
        for(int i = 1;i < nums.size();i++){
            for(int j = 0;j < i ;j++){
                if(nums[i] > nums[j]) dp[i] = max(dp[i],dp[j] + 1);    // 如果严格递增
            }
            if(dp[i] > dp[maxIndex]) maxIndex = i;
        }

        return dp[maxIndex];
    }
};

最长连续递增子序列

leetcode:674. 最长连续递增序列

动态规划

思路

要求连续,所以只需比较上一个元素。(非连续需要比较0~i-1所有元素)

意义依旧是“以nums[i]结尾的(含)递增子序列最长为dp[i]”,所以还要记录一下最大元素。

代码实现

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        vector<int> dp(nums.size(),1);
        int maxIndex = 0;
        for(int i = 1;i < nums.size();i++){
            if(nums[i] > nums[i-1]) dp[i] = max(dp[i],dp[i-1] + 1);
            if(dp[i] > dp[maxIndex]) maxIndex = i;
        }

        return dp[maxIndex];
    }
};

最长重复子数组

leetcode:718. 最长重复子数组

代码实现

/*
以nums[i-1]nums[j-1]结尾的最长公共子数组长度为dp[i][j]

if(nums[i-1] = nums[j-1])
dp[i][j] = dp[i-1][j-1] + 1;

dp[i][0] = 0;dp[0][j] = 0; 其余为0


*/
class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
        int result = 0;
        for(int i = 1;i <= nums1.size();i++){
            for(int j = 1;j <= nums2.size();j++){
                if(nums1[i-1] == nums2[j-1]){
                    dp[i][j] = dp[i-1][j-1] + 1;
                    result = max(result,dp[i][j]);
                }
                
            }
        }

        return result;
    }
};
posted @ 2024-03-28 17:04  Tazdingo  阅读(48)  评论(0)    收藏  举报