「程式碼隨想錄演算法訓練營」第三十八天 | 動態規劃 part11

云雀AC了一整天發表於2024-08-15

1143. 最長公共子序列

題目連結:https://leetcode.cn/problems/longest-common-subsequence/
文章講解:https://programmercarl.com/1143.最長公共子序列.html
題目難度:中等
影片講解:https://www.bilibili.com/video/BV1ye4y1L7CQ
題目狀態:有點思路,但細節有點混亂

思路:

維護一個二維動規陣列dp[i][j],用來記錄長度為i-1的字串text1與長度為j-1的字串text2的最長公共子序列,它的更新條件如下:

  • text1[i - 1] == text2[j - 1],則dp[i][j] = dp[i - 1][j - 1] + 1
  • text1[i - 1] != text2[j - 1],則dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

其中為什麼是i-1和j-1,這個問題和上一題是一樣的。

程式碼:

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int len1 = text1.size();
        int len2 = text2.size();
        vector<vector<int>> dp(len1 + 1, vector<int>(len2 + 1, 0));
        for(int i = 1; i <= len1; ++i) {
            for(int j = 1; j <= len2; ++j) {
                if(text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
                else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
        return dp[len1][len2];
    }
};

1035. 不相交的線

題目連結:https://leetcode.cn/problems/uncrossed-lines/
文章講解:https://programmercarl.com/1035.不相交的線.html
題目難度:中等
影片講解:https://www.bilibili.com/video/BV1h84y1x7MP
題目狀態:看題解

思路:

其本質就是尋找最長公共子序列,也就是上一題。

程式碼:

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

53. 最大子陣列和

題目連結:https://leetcode.cn/problems/maximum-subarray/
文章講解:https://programmercarl.com/0053.最大子序和(動態規劃).html
題目難度:中等
影片講解:https://www.bilibili.com/video/BV19V4y1F7b5
題目狀態:之前使用其他方法AC過

思路一:貪心演算法

遍歷整體陣列,記錄當前總和count,若count出現了負數,說明前面這些陣列都可以刪掉,從下一個元素開始重新遍歷,最終返回最大的count值。

程式碼一:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int count = 0;
        int res = INT_MIN;
        for(int i = 0; i < nums.size(); ++i) {
            count += nums[i];
            if(count > res) res = count;
            if(count <= 0) count = 0;
        }
        return res;
    }
};

思路二:動態規劃

維護一個一維動規陣列dp[i]表示以i元素結尾的最大值(注意是以i元素結尾的,而並不是整體的最大值,整體最大值還需要再去遍歷)。

程式碼二:

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

392. 判斷子序列

題目連結:https://leetcode.cn/problems/is-subsequence/
文章講解:https://programmercarl.com/0392.判斷子序列.html
題目難度:簡單
影片講解:https://www.bilibili.com/video/BV1tv4y1B7ym/
題目狀態:使用其他方式透過,沒有使用動規

思路一:

使用兩個指標ij分別遍歷題目中的序列st,若遇到s[i] == t[j],則i++,最後判斷i的位置,如果i最後的位置是序列s的末尾,表示s遍歷完了,也就是說在t中找到了所有的s

程式碼一:

class Solution {
public:
    bool isSubsequence(string s, string t) {
        if(s.empty()) return true;
        if(t.empty()) return false;
        int i = 0, j = 0;
        while(i < s.size() && j < t.size()) {
            if(s[i] == t[j]) i++;
            j++;
        }
        return i == s.size();
    }
};

思路二:動態規劃

維持一個二維動規陣列dp[i][j]表示在序列s遍歷到i - 1,序列t遍歷到j - 1時,這兩者的相同子序列的長度。

  • s[i - 1] == t[j - 1]時,動規陣列將在前面的基礎上加1
  • 當兩者不相等的時候,動規陣列維持原狀

程式碼二:

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int sLen = s.size();
        int tLen = t.size();
        vector<vector<int>> dp(sLen + 1, vector<int>(tLen + 1, 0));
        for(int i = 1; i <= sLen; ++i) {
            for(int j = 1; j <= tLen; ++j) {
                if(s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
                else dp[i][j] = dp[i][j - 1];
            }
        }
        if(dp[sLen][tLen] == sLen) return true;
        else return false;
    }
};

相關文章