A.每日一题——2435. 矩阵中和能被 K 整除的路径

题目链接:2435. 矩阵中和能被 K 整除的路径(困难)

算法原理:

解法一:动态规划

击败78.82%

时间复杂度O (mnk)

解法二:记忆化搜索DFS

击败24.63%

时间复杂度O (mnk)

整体思路与上面的动态规划大致相同,只是深搜顺序是从(m-1,n-1)开始深搜到(0,0)位置,深搜过程中注意不越界和起点的问题,如果备忘录里存了结果就直接返回备忘录就行,具体可看下面的Java代码,相信大家理解动态规划之后,这个就很容易能看懂

Java代码:

java 复制代码
class Solution {
    //动态规划写法
    public int numberOfPaths(int[][] grid, int k) {
        int MOD=1000000007;
        int m=grid.length,n=grid[0].length;
        int[][][] dp=new int[m+1][n+1][k];
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                //初始化起点部分
                if(i==1&&j==1){
                    int value=grid[0][0]%k;
                    dp[i][j][value]=1;
                    continue;
                }
                //处理非起点部分
                int val=grid[i-1][j-1]%k;//当前格子的余数
                for(int r=0;r<k;r++){
                    //确定余数r需要的前一个状态的余数prev
                    int prev=(r-val+k)%k;
                    dp[i][j][r]=(dp[i][j-1][prev]+dp[i-1][j][prev])%MOD;
                }
            }
        }
        return dp[m][n][0];
    }
}
java 复制代码
class Solution {
    //记忆化搜索DFS写法
    private static final int MOD=1_000_000_007;
    public int numberOfPaths(int[][] grid, int k) {
        int m=grid.length,n=grid[0].length;
        int[][][] memo=new int[m][n][k];
        //备忘录初始化为-1表示没有计算过
        for(int[][] mat:memo)
            for(int[] row:mat)
                Arrays.fill(row,-1);
        return dfs(m-1,n-1,0,memo,grid,k);
    }
    private int dfs(int i,int j,int r,int[][][] memo,int[][] grid,int k){
        if(i<0||j<0) return 0;//出界
        int val=grid[i][j]%k;
        //确定r需要的prev
        int prev=(r-val+k)%k;
        //起点的情况:prev==0时说明r==val
        if(i==0&&j==0) return prev==0?1:0;
        //先去备忘录找找
        if(memo[i][j][r]!=-1) return memo[i][j][r];
        int ret1=dfs(i-1,j,prev,memo,grid,k);
        int ret2=dfs(i,j-1,prev,memo,grid,k);
        return memo[i][j][r]=(ret1+ret2)%MOD;
    }
}
相关推荐
superior tigre3 分钟前
22 括号生成
算法·深度优先
炘爚23 分钟前
C语言(文件操作)
c语言·开发语言
阿蒙Amon26 分钟前
C#常用类库-详解SerialPort
开发语言·c#
凸头1 小时前
CompletableFuture 与 Future 对比与实战示例
java·开发语言
wuqingshun3141591 小时前
线程安全需要保证几个基本特征
java·开发语言·jvm
Moksha2621 小时前
5G、VoNR基本概念
开发语言·5g·php
努力也学不会java1 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
jzlhll1231 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
W.D.小糊涂1 小时前
gpu服务器安装windows+ubuntu24.04双系统
c语言·开发语言·数据库
旖-旎1 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针