算法训练1-day36-动态规划

27 阅读2分钟
  1. 300. 最长递增子序列 dp[i]代表以nums[i]结尾的递增子序列的最长长度 dp数组初始化为1,因为每一个数字本身就是一个子序列且是递增子序列,长度为1 AC代码:
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        // 以nums[i]结尾的递增子序列的最长长度
        vector<int> dp(n, 1);

        int res = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (nums[j] < nums[i]) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            res = max(res, dp[i]);
        }

        return res;
    }
};
  1. 674. 最长连续递增序列

dp[i]代表以nums[i]结尾的最长连续递增子序列的长度 因为连续,所以nums[i]的前一个必定是nums[i-1],因此当nums[i] > nums[i - 1]时,dp[i] = dp[i - 1] + 1;否则dp[i] = 1

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

        return res;
    }
};
  1. 718. 最长重复子数组

dp[i][j]:0-i的nums1与0-j的nums2的公共最长子数组的长度 因此当nums2[j] == nums1[j]dp[i][j]等于dp[i - 1][j - 1] + 1;反之,dp[i][j]应该为0,因为子数组是连续的,nums2[j] != nums1[j]时意味着子数组在这里断掉了,要重新计数

dp[i][j]定义为:以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。那么可以避免写初始化

代码如下:

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();

        // dp[i][j]:0-i的nums1与0-j的nums2的公共最长子数组的长度
        vector<vector<int>> dp(n, vector<int>(m, 0));
        int res = 0;
        for (int i = 0; i < n; ++i) {
            if (nums1[i] == nums2[0]) {
                dp[i][0] = 1;
                res = 1;
            }
        }
        for (int j = 1; j < m; j++) {
            if (nums2[j] == nums1[0]) {
                dp[0][j] = 1;
                res = 1;
            }
        }
        for (int i = 1; i < n; ++i) {
            for (int j = 1; j < m; j++) {
                if (nums1[i] == nums2[j]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                    res = max(res, dp[i][j]);
                } else {
                    dp[i][j] = 0;
                }
            }
        }

        return res;
    }
};

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;
                }
                if (dp[i][j] > result) result = dp[i][j];
            }
        }
        return result;
    }
};