代码随想录算法训练营第五十二天 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组

目录

300.最长递增子序列

674. 最长连续递增序列

718. 最长重复子数组


300.最长递增子序列

题目链接:300. 最长递增子序列

(1)dp[ i ] 表示以第 i 个元素为结尾的递归子序列的长度;

(2)if( nums[ i ] > nums[ j ] )

                dp[ i ] = max( dp[ j ] + 1, dp[ i ] );

(3)dp[ 0 ] = 1; dp[ i ] = 1;

(4)外层循环遍历每个元素,内层循环从头开始遍历到外层元素;

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

674. 最长连续递增序列

题目链接:674. 最长连续递增序列

题目很简单,只需要一重循环,开两个变量:

class Solution {
public:
    int findLengthOfLCIS(vector& nums) {
        int ans = 1;
        int len = 1;
        for(int i = 1; i < nums.size(); ++i){
            if(nums[i] > nums[i-1]) ++len;
            else len = 1;
            if(len > ans)   ans = len;
        }
        return ans;
    }
};

动态规划思路:

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

718. 最长重复子数组

题目链接:718. 最长重复子数组

(1)dp[ i ][ j ] 表示以 nums1 的第 i 个元素、nums2 的第 j 个元素为结尾的重复子数组的长度;

(2)if( nums1[ i ] == nums2[ j ] )        dp[ i ][ j ] = max( dp[ i - 1 ][ j - 1 ] + 1, dp[ i ][ j ] );

(3)if( nums1[ 0 ] == nums2[ 1 ] ) dp[ 0 ][ 0 ] = 1;

        dp[ i ][ j ] = 0;

(4)外层遍历 nums1,内层遍历 nums2;

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

可以看到为了第 0 个元素,需要写额外判断与初始化,所有设 dp数组 0 号位为空状态来使得代码逻辑一致:

class Solution {
public:
    int findLength(vector& nums1, vector& nums2) {
        int ans = 0;
        vector> dp(nums1.size() + 1, vector(nums2.size() + 1, 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;
                }
                if(dp[i][j] > ans)  ans = dp[i][j];
            }
        }
        return ans;
    }
};

你可能感兴趣的:(动态规划,算法,leetcode,c++)