Day53|leetcode 1143. 最長共通部分列、1035. 互いに素な行、53. 最大部分列合計

leetcode 1143. 最長共通部分列

トピックリンク: 1143. 最長共通部分列 - LeetCode

ビデオリンク:動的計画部分列問題の古典的なトピック | LeetCode: 1143. 最長共通部分列_哔哩哔哩_bilibili

 トピックの概要

2 つの文字列 text1 と text2 を指定すると、これら 2 つの文字列の最長の共通部分列の長さを返します。

文字列のサブシーケンスとは、そのような新しい文字列を指します。これは、文字の相対的な順序を変更せずに、元の文字列から一部の文字を削除する (または文字をまったく削除しない) ことによって形成される新しい文字列です。

たとえば、「ace」は「abcde」の部分列ですが、「aec」は「abcde」の部分列ではありません。2 つの文字列の「共通部分列」とは、両方の文字列に共通する部分列です。

2 つの文字列に共通のサブシーケンスがない場合は 0 を返します。

例 1:

   入力: text1 = "abcde"、text2 = "ace"

   出力: 3

   説明: 最も長い共通部分シーケンスは「ace」で、長さは 3 です。

例 2:

   入力: text1 = "abc"、text2 = "abc"

   出力: 3

   説明: 最長の共通部分列は「abc」で、その長さは 3 です。

例 3:

   入力: text1 = "abc"、text2 = "def"

   出力: 0

   説明: 2 つの文字列には共通のサブシーケンスがないため、0 を返します。

一連の考え

1. dp 配列の意味を確認する

dp[i][j]: 長さ [0, i - 1] の文字列 text1 と長さ [0, j - 1] の文字列 text2 の最長共通部分列は dp[i][j] です (この定義は、次のコードの実装をより便利にするためのものです)

2. 再帰式を決定する

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]) (条件: text1[i - 1] が text2[j - 1] と等しくない)

3. 配列の初期化

dp[i][0] = 0、dp[0][j] = 0

4. 走査順序を決定する

上の図から、dp[i][j] は左辺、上辺、左上辺から導出できるため、順序は上から下、左から右であることがわかります。 

5. 配列を出力します。

コード

lass Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        vector<vector<int>> dp(text1.size() + 1,vector<int>(text2.size() + 1,0));
        for(int i = 1;i <= text1.size();i++) {
            for(int j = 1;j <= text2.size();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[text1.size()][text2.size()];

    }
};

leetcode 1035. 切り離された行

トピックリンク: 1035. 不連続な行 - LeetCode

ビデオリンク:動的計画法の後続問題、薬を変えずにスープを変える | LeetCode: 1035. Disjoint Lines_哔哩哔哩_bilibili

 トピックの概要

整数を2 つの別々の水平線に指定された順序で nums1書き込み ますnums2

nums1[i]和nums2[j]これで、両方を満たす必要がある 2 つの数値を結ぶ線を引くことができます。

  •  nums1[i] == nums2[j]
  • また、描かれた線は他の線(非水平線)と交差しません。

線は端点であっても交差できないことに注意してください。各数値は 1 つの線にのみ属することができます。

この方法で線を描画し、描画できる線の最大数を返します。

 

例 1:

入力: nums1 = [1,4,2]、nums2 = [1,2,4]
出力: 2
説明:上の図に示すように、交差しない 2 本の線を描画できます。
しかし、nums1[1]=4 から nums2[2]=4 までの線が nums1[2]=2 から nums2[1]=2 までの線と交差するため、3 番目の互いに素な線を引くことはできません。

例 2:

入力: nums1 = [2,5,1,2,5]、nums2 = [10,5,2,1,5,2]
出力: 3

一連の考え

実は、この質問の本質は前の質問なのですが、前の質問の記述が変更されており、コードも変わっていませんが、名前が変更されています。この問題は、描画される接続の最大数を見つけることですが、実際には、2 つの文字列の最長の共通部分列の長さを見つけることです。

コード

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

    }
};

leetcode 53. 最大サブシーケンス合計

トピックリンク: 53. サブ配列の最大合計 - LeetCode

ビデオリンク:複雑に見えますが、実際は単純な動的プログラミング | LeetCode: 53. 最大部分列 sum_哔哩哔哩_bilibili

 トピックの概要

整数配列 nums を指定して、合計が最大になる連続した部分配列を見つけて (部分配列には少なくとも 1 つの要素が含まれます)、その最大合計を返します。

例:

   入力: [-2,1,-3,4,-1,2,1,-5,4]

   出力: 6

   説明: 連続する部分配列 [4,-1,2,1] の合計が最大の 6 です。

一連の考え

この質問は以前にも貪欲に行われました!

次に、モーション ルールを使用してこれをもう一度実行します。

1. dp 配列の意味を確認する

dp[i]: nums[i] (添え字 i を含む) で終わる連続部分列の合計の最大値は dp[i] です

2. 再帰式を決定する

dp[i - 1] + nums[i] (前のサブシーケンスの合計を計算し続ける)

nums[i] (前の連続したサブシーケンスを合計しないで、計算を再開します)

したがって、dp[i] = max(dp[i - 1] + nums[i], nums[i]);

3. 配列の初期化

dp[0] = 数値[0]

4. 走査順序を決定する

前から後ろへ

5. 配列を出力します。

コード

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

おすすめ

転載: blog.csdn.net/m0_74583479/article/details/132641354
おすすめ