代码随想录算法训练营 day 53: ● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划

83 阅读2分钟

1143. Longest Common Subsequence

主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同

如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。

即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int row = text1.length();
        int col = text2.length();

        int[][] dp = new int[row+1][col+1];


        for(int i=1; i<=row; i++) {
            char char1 = text1.charAt(i - 1);
            for(int j=1; j<=col; j++) {
                char char2 = text2.charAt(j - 1);
                if(char1 == char2) {
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
                else {
                    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }

        return dp[row][col];

    }
}

1035. Uncrossed Lines 这道题跟上一题完全一样,但思路就是没看出来。相当于求两个数组的最大公共子集,考虑顺序。

class Solution {
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int[][] dp = new int[nums1.length+1][nums2.length+1];

        for(int i=1; i<=nums1.length; i++) {
            for(int j=1; j<=nums2.length; j++) {
                if(nums1[i-1] == nums2[j-1]) {
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
                else {
                    dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);
                }
            }
        }

        return dp[nums1.length][nums2.length];
    }
}

53. Maximum Subarray 这题贪心的做法跟动规思路很不一样,不能混淆。 动规的话,dp数组存放数组[0,i]的最大和。转移公式为 dp[i] = max(dp[i-1] + nums[i], nums[i]) 要注意并不一定最后一个dp元素存放最大值,所以要加一个变量存最大值。

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums.length == 0) {
            return 0;
        }

        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        int result = dp[0];

        for(int i=1; i<nums.length; i++) {
            dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
            //System.out.println(Arrays.toString(dp));

            if(result < dp[i]) {
                result = dp[i];
            }

        }

        return result;

    }
}