10、LIS 和 LCS 问题

内容来自刘宇波老师玩转算法面试

1、LIS 问题

300 - 最长递增子序列

更多问题
376 - 摆动序列

1.1、思路

image
image

1.2、图示

image
image

1.3、动态规划

public static int lengthOfLIS(int[] nums) {
    if (nums == null || nums.length == 0) return 0;
    if (nums.length == 1) return 1;

    // memo[i] = nums[0 ... i] 选择数字 nums[i] 可以获得的最长上升子序列的长度
    int[] memo = new int[nums.length];
    Arrays.fill(memo, 1);

    for (int i = 1; i < nums.length; i++) {
        // 求解 memo[i]
        for (int j = 0; j <= i - 1; j++) {
            if (nums[i] > nums[j]) memo[i] = Math.max(memo[i], 1 + memo[j]);
        }
    }

    return Arrays.stream(memo).max().getAsInt();
}

2、LCS 问题

1143 - 最长公共子序列

image

2.1、思路

image

2.2、图示

image

2.3、记忆化搜索

public class Solution {

    private static int[][] memo;

    public static int longestCommonSubsequence(String text1, String text2) {
        if (text1 == null || text2 == null) return 0;

        int m = text1.length();
        int n = text2.length();
        memo = new int[m][n];
        for (int[] arr : memo) Arrays.fill(arr, -1);

        return dp(text1.toCharArray(), text2.toCharArray(), m - 1, n - 1);
    }

    /**
     * s1[0 ... m] 和 s2[0 ... n] 的最长公共子序列
     */
    private static int dp(char[] s1, char[] s2, int m, int n) {
        if (m < 0 || n < 0) return 0;

        if (memo[m][n] != -1) return memo[m][n];

        int res = -1;
        if (s1[m] == s2[n]) res = 1 + dp(s1, s2, m - 1, n - 1);
        else res = Math.max(dp(s1, s2, m - 1, n), dp(s1, s2, m, n - 1));
        memo[m][n] = res;

        return res;
    }
}

3、更多话题

3.1、单源最短路径算法

image

3.2、最长上升子序列的具体解

image

3.3、01 背包问题的具体解

image

posted @ 2023-05-26 20:22  lidongdongdong~  阅读(13)  评论(0编辑  收藏  举报