hot100-一刷-16多维动态规划(共5道题)

62. 不同路径

题目链接

题目描述

image

代码实现

分析:

代码:

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        //dp[i][j] = dp[i-1][j] + dp[i][j-1];
        for (int i = 0; i<m; i++) dp[i][0] = 1;
        for (int j = 0; j<n; j++) dp[0][j] = 1;
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
}

64. 最小路径和

题目链接

题目描述

image

提示:

m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 200

代码实现

分析:

代码:

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        // dp[i][j] 表示 从[0][0]到[i][j]路径上最小的数字和。
        int[][] dp = new int[m][n];
        dp[0][0] = grid[0][0];
        for(int i = 1; i < m; i++) dp[i][0] = dp[i-1][0] + grid[i][0];
        for(int j = 1; j < n; j++) dp[0][j] = dp[0][j-1] + grid[0][j];

        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1]) + grid[i][j];
            }
        }
        return dp[m-1][n-1];
    }
}

5. 最长回文子串

题目链接

题目描述

给你一个字符串 s,找到 s 中最长的 回文 子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母组成

代码实现

分析:

代码:

class Solution {
    public String longestPalindrome(String s) {
        char[] chars = s.toCharArray();
        int n = s.length();
        // [i,j]是回文依赖于 [i+1, j-1]是回文 且 s[i] = s[j]
        // 初始默认都没匹配上
        boolean[][] dp = new boolean[n][n];
        int res = 0;
        String ans = "";
        // 从下到上,
        for(int i = n-1; i >=0; i--){
            // 从左到右
            for(int j = i; j < n; j++){
                if(chars[i] == chars[j]){
                    // i和j相等, 或者,i比j小1, 分别是 ‘a’  ‘aa’这两种情况
                    if(j - i <= 1){
                        dp[i][j] = true;
                        res = Math.max(j-i, res);
                        if(j - i >= res){
                            ans = s.substring(i, j+1);
                        }
                    }else { // 'cabac'这种情况,继续判断[i+1, j-1]的情况
                        if(dp[i+1][j-1]){  //从下到上,从左到右的遍历顺序,此时用到的是已经更新过的dp[i+1][j-1]
                            dp[i][j] = true;
                            res = Math.max(j-i, res);
                            if(j - i >= res){
                                ans = s.substring(i, j+1);
                            }
                        }
                    }
                }
            }
        }
        return ans;
    }
}

// 简洁版
class Solution {
    public String longestPalindrome(String s) {
        char[] chars = s.toCharArray();
        int n = s.length();

        // [i,j]是回文依赖于 [i+1, j-1]是回文 且 s[i] = s[j]
        // 初始默认都没匹配上
        boolean[][] dp = new boolean[n][n];

        int res = 0;
        String ans = "";
        // 从下到上,
        for(int i = n-1; i >=0; i--){
            // 从左到右
            for(int j = i; j < n; j++){
                if(chars[i] == chars[j] && (j-i <=1 || dp[i+1][j-1])){
                    // i和j相等, 或者,i比j小1, 分别是 ‘a’  ‘aa’这两种情况
                    // 'cabac'这种情况,继续判断[i+1, j-1]的情况 //从下到上,从左到右的遍历顺序,此时用到的是已经更新过的dp[i+1][j-1]
                    dp[i][j] = true;
                    res = Math.max(j-i, res);
                    if(j - i >= res){
                        ans = s.substring(i, j+1);
                    }
                }
            }
        }
        return ans;
    }
}

1143. 最长公共子序列

题目链接

题目描述

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

输入:text1 = "abcde", text2 = "ace"
输出:3
解释:最长公共子序列是 "ace" ,它的长度为 3 。

示例 2:

输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc" ,它的长度为 3 。

示例 3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0 。

提示:

1 <= text1.length, text2.length <= 1000
text1 和 text2 仅由小写英文字符组成。

代码实现

分析:

代码:

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length();
        int n = text2.length();
        // dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]
        int[][] dp = new int[m+1][n+1];

        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                if(text1.charAt(i-1) == text2.charAt(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]);
                }
            }
        }
        // [0, m-1]的text1 和 [0,n-1] 的text2 的最长公共子序列长度
        return dp[m][n];
    }
}

72. 编辑距离

题目链接

题目描述

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数  。

你可以对一个单词进行如下三种操作:

插入一个字符
删除一个字符
替换一个字符

示例 1:

输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

示例 2:

输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

提示:

0 <= word1.length, word2.length <= 500
word1 和 word2 由小写英文字母组成

代码实现

分析:

代码:

class Solution {
    public int minDistance(String word1, String word2) {
        int len1 = word1.length();
        int len2 = word2.length();
        // dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]
        int[][] dp = new int [len1+1][len2+1];
        for (int i = 1; i <=len1; i++) dp[i][0] = i; // word2为空,word1有几个单词,word1就删除几个单词
        for (int j = 1; j <= len2; j++) dp[0][j] = j;// word1为空,word2有几个单词, word1就增加几个单词

        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                if(word1.charAt(i-1) == word2.charAt(j-1)){
                    // 无操作
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    // [[插入(word1插入一个和word2一样的单词,相当于word2删除那个单词), 删除],  替换]
                    dp[i][j] = Math.min(Math.min(dp[i][j-1],dp[i-1][j]), dp[i-1][j-1]) + 1;
                }
            }
        }
        return dp[len1][len2];
    }
}
posted @ 2024-12-31 18:32  chendsome  阅读(2)  评论(0编辑  收藏  举报