Leetcode 刷题记录 20 —— 多维动态规划

本系列为笔者的 Leetcode 刷题记录,顺序为 Hot 100 题官方顺序,根据标签命名,记录笔者总结的做题思路,附部分代码解释和疑问解答,01~07为C++语言,08及以后为Java语言。

01 不同路径

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

class Solution {
    public int uniquePaths(int m, int n) {
        //dp[i][j]代表走到(i, j)点位共有几条不同路径
        int[][] dp = new int[m][n]; //m行 n列

        //边界条件
        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];
    }
}

02 最小路径和

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

class Solution {
    public int minPathSum(int[][] grid) {
        //特殊情况判断
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }

        int m = grid.length;
        int n = grid[0].length;

        //dp[i][j]代表走到(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];
    }
}

03 最长回文子串

在这里插入图片描述

class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        int maxLen = 1;
        int begin = 0;

        //dp[i][j]表示[i, j]区间是否为字符串
        boolean[][] dp = new boolean[n][n];
        
        //边界条件
        for(int i=0; i<n; i++){
            dp[i][i] = true;
        }

        for(int j=0; j<n; j++){
            for(int i=0; i<=j; i++){
                //状态转移方程
                if(s.charAt(i) != s.charAt(j)){
                    dp[i][j] = false;
                }else{
                    if((j-i) < 3){
                        dp[i][j] = true;
                    }else{
                        dp[i][j] = dp[i+1][j-1];
                    }
                }

                if (dp[i][j] && j - i + 1 > maxLen) {
                    maxLen = j - i + 1;
                    begin = i;
                }
            }
        }
        return s.substring(begin, begin + maxLen);
        
    }
}

04 最长公共子序列

在这里插入图片描述

在这里插入图片描述

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

        //dp[i][j]表示text1[0, i]和text2[0, j]的公共子序列长度
        int[][] dp = new int[m+1][n+1];

        //边界条件
        dp[0][0] = 0;
        for(int i=1; i<m; i++){
            dp[i][0] = 0;
        }
        for(int j=1; j<n; j++){
            dp[0][j] = 0;
        }

        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-1][j], dp[i][j-1]);
                }
            }
        }
        return dp[m][n];
    }
}

05 编辑距离

在这里插入图片描述

在这里插入图片描述

class Solution {
    public int minDistance(String word1, String word2) {
        int m = word1.length();
        int n = word2.length();

        //dp[i][j] 表示 word1 到 i 位置转换成 word2 到 j 位置需要最少步数
        int[][] dp = new int[m+1][n+1];

        //边界条件
        dp[0][0] = 0;
        for(int i=1; i<=m; i++){
            dp[i][0] = dp[i-1][0] + 1;
        }
        for(int j=1; j<=n; j++){
            dp[0][j] = dp[0][j-1] + 1;
        }

        for(int i=1; i<=m; i++){ //这里不按下标取字母,而按第几个取字母
            for(int j=1; j<=n; j++){
                //状态转移方程
                if(word1.charAt(i-1) == word2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
                }
            }
        }
        return dp[m][n];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值