力扣2684---矩阵中移动的最大次数(DFS,Java、中等题)

目录

题目描述:

思路描述:

代码:

纯递归:

带有记忆化搜索的递归:


题目描述:

给你一个下标从 0 开始、大小为 m x n 的矩阵 grid ,矩阵由若干 整数组成。

你可以从矩阵第一列中的 任一 单元格出发,按以下方式遍历 grid

  • 从单元格 (row, col) 可以移动到 (row - 1, col + 1)(row, col + 1)(row + 1, col + 1) 三个单元格中任一满足值 严格 大于当前单元格的单元格。

返回你在矩阵中能够 移动最大 次数。

示例 1:

复制代码
输入:grid = [[2,4,3,5],[5,4,9,3],[3,4,2,11],[10,9,13,15]]
输出:3
解释:可以从单元格 (0, 0) 开始并且按下面的路径移动:
- (0, 0) -> (0, 1).
- (0, 1) -> (1, 2).
- (1, 2) -> (2, 3).
可以证明这是能够移动的最大次数。

示例 2:

复制代码
复制代码
输入:grid = [[3,2,4],[2,1,9],[1,1,7]]
输出:0
解释:从第一列的任一单元格开始都无法移动。

提示:

  • m == grid.length
  • n == grid[i].length
  • 2 <= m, n <= 1000
  • 4 <= m * n <= 10^5
  • 1 <= grid[i][j] <= 10^6

思路描述:

从第一列开始进行有条件的深度优先搜索即可,如果纯递归的话,会超时。

递归加上记忆化搜索,既可以以比较好的时间复杂度通过了。

代码:

纯递归:

java 复制代码
public class Solation{
    /**
     * 从单元格 (row, col) 可以移动到 (row - 1, col + 1)、(row, col + 1) 和 (row + 1, col + 1) 三个单元格中任一满足值 严格 大于当前单元格的单元格。
     * 返回你在矩阵中能够 移动 的 最大 次数。
     */
    int[][] direction={{-1,1},{0,1},{1,1}};
    int MaxStep=Integer.MIN_VALUE;
    public int maxMoves(int[][] grid) {
        for(int i=0;i<grid.length;i++){
            myfun(grid,i,0,0);
        }
        return MaxStep;
    }
    public void myfun(int[][] grid,int row,int col,int step){
        if(step>=grid[0].length){
            MaxStep=Math.max(step,MaxStep);
            return;
        }
        boolean flag=false;
        for(int i=0;i<direction.length;i++){
            if(row+direction[i][0]<grid.length &&col+direction[i][1]<grid[0].length && row+direction[i][0]>=0 &&row+direction[i][1]>=0 &&   grid[row][col]<grid[row+direction[i][0]][col+direction[i][1]]){
                flag=true;
                myfun(grid,row+direction[i][0],col+direction[i][1],step+1);
            }
        }
        if(!flag){
            MaxStep=Math.max(step,MaxStep);
        }
    }
}

带有记忆化搜索的递归:

java 复制代码
class Solution {
    int m;
    int n;
    int[][] direction = new int[][]{{-1, 1}, {0, 1}, {1, 1}};
    public int maxMoves(int[][] grid) {
        m = grid.length;
        n = grid[0].length;

        int[][] dis = new int[m][n];
        for(int i = 0; i < m; i++){
            Arrays.fill(dis[i], -1);
        }

        int result = 0;

        for(int i = 0; i < m; i++){
            result = Math.max(result, findPath(i, 0, grid, dis) );
        }
        return result;
    }

    private int findPath(int x, int y, int[][] grid, int[][] dis){
        if(dis[x][y] != -1){
            return dis[x][y];
        }

        int maxLength = 0;
        for(int i = 0; i < 3; i++){
            int new_x = x + direction[i][0];
            int new_y = y + direction[i][1];
            if(new_x >= 0 && new_x < m && new_y < n && grid[new_x][new_y] > grid[x][y]){
                maxLength = Math.max(maxLength, findPath(new_x, new_y, grid, dis) + 1);
            }
        }

        dis[x][y] = maxLength;
        return dis[x][y];
    }
}
相关推荐
Tisfy1 分钟前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java28 分钟前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
丶Darling.30 分钟前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
一个不知名程序员www2 小时前
leetcode第189题:轮转数组(C语言版)
c语言·leetcode
一叶祇秋3 小时前
Leetcode - 周赛417
算法·leetcode·职场和发展
FindYou.5 小时前
C - Separated Lunch
算法·深度优先
夜雨翦春韭5 小时前
【代码随想录Day30】贪心算法Part04
java·数据结构·算法·leetcode·贪心算法
一直学习永不止步5 小时前
LeetCode题练习与总结:H 指数--274
java·数据结构·算法·leetcode·数组·排序·计数排序
戊子仲秋6 小时前
【LeetCode】每日一题 2024_10_2 准时到达的列车最小时速(二分答案)
算法·leetcode·职场和发展
￴ㅤ￴￴ㅤ9527超级帅7 小时前
LeetCode hot100---二叉树专题(C++语言)
c++·算法·leetcode