[Java 算法] 动态规划2

练习一 : 解码方法

91. 解码方法 - 力扣(LeetCode)

java 复制代码
class Solution {
        public int numDecodings(String s) {
            int len = s.length();
            char[] ch = s.toCharArray();
            int [] arr = new int[len];
            for(int i = 0;i<len;i++){
                arr[i] = ch[i]-'0';
            }
            if(arr[0] == 0){
                return 0;
            }
            int[] dp = new int [len+1];
            dp[0] = 1;//将第一位为0过滤掉了
            if(len == 1){
                return dp[0];
            }
            int two = arr[0]*10+arr[1];
            if(arr[1] == 0){
            // 0 不能单独解码,只能看是否是 10/20
                dp[1] = (two == 10 || two == 20) ? 1 : 0;
            }else if(two > 26){
                dp[1] = 1;
            }else{
                dp[1] = 2;
            }
            
            if(len == 2){
                return dp[1];
            }
            for(int i = 2;i<len;i++){
                int now = arr[i];
                int preTwo = arr[i-1]*10 + now;
                if(dp[i-1] == 0&&dp[i-2] == 0){
                    return 0;
                }
                if(now == 0){//单独解码失败
                    // 当前是0,必须和前一位组合 10/20,否则无解
                    if(preTwo !=10 && preTwo!=20){
                        return 0;
                    }
                    dp[i] = dp[i-2];
                }
                else if(preTwo <10 || preTwo>26){
                    // 不能组合,只能单独解码
                    dp[i] = dp[i-1];
                }
                else{
                    // 既能单独又能组合
                    dp[i] = dp[i-1]+dp[i-2];
                }
            }
            return dp[len-1];
        }
    }

算法原理 :

状态表示 : dpi : 解码到 i 位置的解码方法数 ;

状态转移方程 : dpi : 可以在 dpi-1 方法数的基础上从 i 位置解码 , 解码一个字符 ; 也可以在 dpi-2 方法数的基础上从 i-1 位置解码 , 解码两个字符

细节问题 :

代码细节 :

  1. 预处理字符串 , 先将字符串拆分为字符数组 , 再将字符数组转为整型数组 , 方便计算
  2. 边界判断 , 重点预处理前两个字符
  3. 重点 : 动态规划

练习二 : 不同路径 1

62. 不同路径 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m+1][n+1];
        dp[1][0] = 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][n];
    }
}

算法原理 :

dpij : 到达 i,j 位置的路径数

由于到达 i,j 位置 可以从 i-1,j ,或者从 i,j-1 走一步到达 ; 所以dpij = dpi-1j+dpij-1

初始化问题 : 防止下标越界 , 可以在数组初始化时多加一行一列 , 将第 0 行和第 0 列分别初始化 , 为了不影响最终结果 , 只将 dp10 初始化为 1 , 其余为 0

返回值问题 : 由于多加一行一列 , dp 数组中的 i,j 映射到原路径中应该是 i-1,j-1 ; 所以最终返回的位置是原路径中的 m-1,n-1 , 对应到 dp 数组中就是 dpmn

练习三 : 不同路径2

63. 不同路径 II - 力扣(LeetCode)

java 复制代码
class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;//行数
        int n = obstacleGrid[0].length;//列数
        int[][] dp = new int[m+1][n+1];
        dp[0][1] = 1;
        for(int i = 1;i<=m;i++){
            for(int j = 1;j<=n;j++){
                if(obstacleGrid[i-1][j-1] == 1){
                    dp[i][j] = 0;
                }else{
                    dp[i][j] = dp[i-1][j]+dp[i][j-1];
                }
            }
        }
        return dp[m][n];
    }
}

算法原理 :

大体思路同上题 ,

细节 : 有障碍物时 : dpij = 0 ; 无障碍物时 : dpij = dpi-1j+dpij-1

练习四 : 下降路径最小和

931. 下降路径最小和 - 力扣(LeetCode)

java 复制代码
class Solution {
    public int minFallingPathSum(int[][] matrix) {
        int m = matrix.length;//行数
        int n = matrix[0].length;//列数
        int[][] dp = new int[m+1][n+2];
        for(int i = 1;i<=m;i++){
            dp[i][0] = dp[i][n+1] = Integer.MAX_VALUE;
        }
        for(int i =1;i<=m;i++){
            for(int j = 1;j<=n;j++){
                dp[i][j] = Math.min(dp[i-1][j],Math.min(dp[i-1][j-1],dp[i-1][j+1]))+matrix[i-1][j-1];
            }
        }
        int ret = Integer.MAX_VALUE;
        for(int i = 1;i<=n;i++){
            ret = Math.min(ret,dp[m][i]);
        }
        return ret;
    }
}

算法原理 :

dpij : 到达 i,j 位置的最小下降路径

返回值 : 需要遍历最后一行

相关推荐
余俊晖15 分钟前
多模态大模型细粒度视觉理解:Vision-OPD在线策略自蒸馏技术方案概述
人工智能·深度学习·算法·多模态·opd
脚踏实地皮皮晨29 分钟前
003003001_Grid控件
开发语言·windows·算法·c#·visual studio
Hi李耶41 分钟前
【LeetCode】6-Z字形变换
算法·leetcode·职场和发展
XiaoYu1__1 小时前
算法进阶·其一:用SCC、Tarjan算法与缩点思想解决有向图的连通关系及2-SAT问题的拓展
算法
小O的算法实验室1 小时前
AAAI-26,全局相关性学习:通过谱图神经网络增强进化算法
神经网络·学习·算法
段一凡-华北理工大学1 小时前
AI推动工业智能化转型~系列文章07:分类与诊断算法体系:故障识别的完整工具箱
数据库·人工智能·算法·机器学习·分类·数据挖掘·高炉炼铁智能化
简信CRM1 小时前
适合离散制造中小工厂 MES 系统推荐
算法·机器学习·制造
AKA__Zas1 小时前
芝士算法(前缀和2.0)
java·数据结构·算法·leetcode·哈希算法·学习方法
皓月斯语1 小时前
B3867 [GESP202309 三级] 小杨的储蓄 题解
c++·算法·题解
半夢半醒12 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加菱形、平行四边形、圆角矩形,文本居中显示
算法·c#·流程图