2024.3.16力扣每日一题——矩阵中移动的最大次数

2024.3.16

      • 题目来源
      • 我的题解
        • [方法一 深度优先遍历(超时)](#方法一 深度优先遍历(超时))
        • [方法二 动态规划](#方法二 动态规划)
        • [方法三 广度优先遍历](#方法三 广度优先遍历)

题目来源

力扣每日一题;题序:2684

我的题解

方法一 深度优先遍历(超时)

从第一列的每一行开始进行深度优先遍历,满足条件才往下进行遍历,否则更新当前结果。

直接深度搜索会超时,可以改为记忆化搜索,记忆化搜索版本自己完成。
时间复杂度 :O( m n C mnC mnC)。m是行,n是列,C等于3
空间复杂度:O(1)

java 复制代码
int res=0;
public int maxMoves(int[][] grid) {
    int m=grid.length;
    int n=grid[0].length;
    // int res=0;
    for(int i=0;i<m;i++){
        dfs(grid,i,i,0,0);
    }
    return res;
}
public void dfs(int[][] grid,int start,int row,int col,int count){
    boolean flag=false;
    int m=grid.length;
    int n=grid[0].length;
    for(int i=row-1;i<=row+1&&col+1<n;i++){
        if(i<0||i==m)
            continue;
        int t=grid[i][col+1];
        int cur=grid[row][col];
        if(cur<t){
            dfs(grid,start,i,col+1,count+1);
            flag=true;
        }
    }
    if(flag)
        res=Math.max(res,count+1);
}
方法二 动态规划

转移方程:dp[i][j] = max(dp[i-1][j+1], dp[i][j+1], dp[i+1][j+1])
时间复杂度:O(mn)

空间复杂度:O(mn)

java 复制代码
public int maxMoves(int[][] grid) {
    // dp 或者记分板的dfs
    // dp思路:自右上角开始,一列一列遍历,时间复杂度:O(nm)
    // 结果:答案应该在第一列中,可以取第一列的最大值
    // 状态转移方程:
    // dp[i][j] = max(dp[i-1][j+1], dp[i][j+1], dp[i+1][j+1])
    int m = grid.length;
    if (m == 0) return 0;
    int n = grid[0].length;
    if (n == 0) return 0;
    int[][] dp = new int[m][n];

    // 初始化:最后一列全为0,因为不存在
    // 从倒数第二列开始
    for (int j = n - 2; j >= 0; j--) {
        for (int i = 0; i < m; i++) {
            int mx = 0;
            if (grid[i][j] < grid[i][j + 1]) {
                mx = Math.max(mx, dp[i][j + 1] + 1);
            }
            if (i + 1 < m && grid[i][j] < grid[i + 1][j + 1]) {
                mx = Math.max(mx, dp[i + 1][j + 1] + 1);
            }
            if (i - 1 >= 0 && grid[i][j] < grid[i - 1][j + 1]) {
                mx = Math.max(mx, dp[i - 1][j + 1] + 1);
            }
            dp[i][j] = mx;
        }
    }

    int res = 0;
    for (int i = 0; i < m; i++) {
        res = Math.max(res, dp[i][0]);
    }
    return res;
}
方法三 广度优先遍历

首先把所有行坐标加入到集合中,作为出发点。然后对其依次遍历,对每一个单元格,找到下一个列的相邻单元格,并判断是否严格大于当前单元格。

如果是,说明可以移动到达。把所有可到达的单元格行坐标加到集合中,并用于下一轮的搜索。

当到达最后一列或者集合为空,搜索结束,返回矩阵中移动的最大次数。
时间复杂度:O(mn)

空间复杂度:O(n)

java 复制代码
public int maxMoves(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    Set<Integer> q = new HashSet<>();
    for (int i = 0; i < m; i++) {
        q.add(i);
    }
    for (int j = 1; j < n; j++) {
        Set<Integer> q2 = new HashSet<>();
        for (int i : q) {
            for (int i2 = i - 1; i2 <= i + 1; i2++) {
                if (0 <= i2 && i2 < m && grid[i][j - 1] < grid[i2][j]) {
                    q2.add(i2);
                }
            }
        }
        q = q2;
        if (q.isEmpty()) {
            return j - 1;
        }
    }
    return n - 1;
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

相关推荐
阿蒙Amon13 小时前
C#每日面试题-常量和只读变量的区别
java·面试·c#
执携13 小时前
算法 -- 冒泡排序
数据结构·算法
寻星探路14 小时前
【算法专题】滑动窗口:从“无重复字符”到“字母异位词”的深度剖析
java·开发语言·c++·人工智能·python·算法·ai
程序员小白条14 小时前
面试 Java 基础八股文十问十答第八期
java·开发语言·数据库·spring·面试·职场和发展·毕设
萤丰信息14 小时前
从 “钢筋水泥” 到 “数字神经元”:北京 AI 原点社区重构城市进化新逻辑
java·大数据·人工智能·安全·重构·智慧城市·智慧园区
wen__xvn14 小时前
代码随想录算法训练营DAY14第六章 二叉树 part02
数据结构·算法·leetcode
Ka1Yan14 小时前
[数组] - 代码随想录(2-6)
数据结构·算法·leetcode
你要飞15 小时前
考研线代第四课:线性方程组
笔记·线性代数·考研·矩阵
week_泽15 小时前
第5课:短期记忆与长期记忆原理 - 学习笔记_5
java·笔记·学习·ai agent
像风一样自由15 小时前
android native 中的函数动态注册方式总结
android·java·服务器·安卓逆向分析·native函数动态注册·.so文件分析