Day53|leetcode 1143. 가장 긴 공통 하위 시퀀스, 1035. 분리된 라인, 53. 최대 하위 시퀀스 합계

leetcode 1143. 가장 긴 공통 부분 시퀀스

주제 링크: 1143. 가장 긴 공통 부분 수열 - LeetCode

비디오 링크: 동적 프로그래밍 부분 수열 문제의 고전적인 주제 | LeetCode: 1143. 가장 긴 공통 부분 수열_哔哩哔哩_bilibili

 주제 개요

두 문자열 text1과 text2가 주어지면 이 두 문자열의 가장 긴 공통 부분 수열의 길이를 반환합니다.

문자열의 하위 시퀀스는 이러한 새 문자열을 참조합니다. 즉, 문자의 상대적 순서를 변경하지 않고 원래 문자열에서 일부 문자를 삭제(또는 문자를 삭제하지 않음)하여 형성된 새 문자열입니다.

예를 들어, "ace"는 "abcde"의 하위 시퀀스이지만 "aec"는 "abcde"의 하위 시퀀스가 ​​아닙니다. 두 문자열의 "공통 하위 시퀀스"는 두 문자열이 공통으로 갖는 하위 시퀀스입니다.

두 문자열에 공통 하위 시퀀스가 ​​없으면 0을 반환합니다.

예시 1:

   입력: text1 = "abcde", text2 = "ace"

   출력: 3

   설명: 가장 긴 공통 부분 수열은 길이가 3인 "ace"입니다.

예 2:

   입력: text1 = "abc", text2 = "abc"

   출력: 3

   설명: 가장 긴 공통 부분 수열은 "abc"이고 길이는 3입니다.

예시 3:

   입력: text1 = "abc", text2 = "def"

   출력: 0

   설명: 두 문자열에 공통 하위 시퀀스가 ​​없습니다. 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

 주제 개요

두 개의 별도 수평선에 주어진 순서대로  nums1정수  를 쓰십시오 nums2.

nums1[i]和nums2[j]이제 두 숫자를 모두 만족시켜야 하는 두 숫자를 연결하는 선을 그릴 수 있습니다 .

  •  nums1[i] == nums2[j]
  • 그리고 그려진 선은 다른 선(비수평선)과 교차하지 않습니다.

선은 끝점에서도 교차할 수 없습니다. 각 번호는 하나의 선에만 속할 수 있습니다.

이런 방식으로 선을 그리고 그릴 수 있는 최대 선 수를 반환합니다.

 

예시 1:

입력: nums1 = [1,4,2], nums2 = [1,2,4]
 출력: 2
 설명: 위 그림과 같이 교차하지 않는 두 개의 선을 그릴 수 있습니다. 
그러나 nums1[1]=4에서 nums2[2]=4까지의 선이 nums1[2]=2에서 nums2[1]=2까지의 선과 교차하기 때문에 세 번째 분리된 선을 그릴 수 없습니다.

예 2:

입력: nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
 출력: 3

생각의 기차

사실 이 질문의 본질은 이전 질문인데 이전 질문의 설명이 변경되었고 심지어 코드도 변경되지 않았지만 이름이 변경되었습니다. 이 질문은 그려진 연결의 최대 수를 구하는 것이지만 실제로는 두 문자열의 가장 긴 공통 부분 수열의 길이를 구하는 것입니다!

암호

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가 주어지면 최대 합계를 갖는 연속 하위 배열(하위 배열에는 최소한 하나의 요소가 포함되어 있음)을 찾고 최대 합계를 반환합니다.

예:

   입력: [-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