小U的最大连续移动次数问题| 豆包MarsCode AI 刷题

161 阅读3分钟

题目描述

直接给出题目链接 小U的最大连续移动次数问题 - MarsCode

将题目精炼一下:

一个m×nm \times n的矩阵,a[x][y]代表每个坐标(x,y)的高度,小U每次只能走上坡和下坡,也就是不能到高度相同的地方。并且上下坡需要交替执行。求小U在这个矩阵中最多能连续移动多少次?

解题思路

这个题目是标准的dfs题型,唯一的不同的就是约束条件多了两条:

一个是不能到相同高度的地方。

第二个是上下坡必须交替执行。

关键步骤如下:

  1. DFS函数的实现:

    • dfs(int x, int y, ...) 是一个递归函数,尝试从点 (x, y) 出发探索所有可能的路径。
    • 变量 upOrDown 用于指示当前路径是否处于上坡(1)还是下坡(0)状态。
    • visited 数组用于记录当前路径中已经访问过的节点,防止重复访问和形成环。
  2. 递归遍历:

    • 对于每个点 (nx, ny),判断是否在数组范围内。
    • 检查是否已经访问过该点,避免重复。
    • 检查高度差是否符合上坡或下坡的条件,并判断是否是上下坡交替访问。
    • 递归调用 dfs 进行深度遍历,并通过 Math.max 保持最大移动次数。
  3. 回溯:

    • 在递归完成后,回溯时将 visited[x][y] 重置为未访问状态,以便尝试新的路径。
  4. 全局遍历:

    • solution(int m, int n, int[][] a) 遍历每个起始点 (i, j),分别计算上坡和下坡的最大步数。
    • 使用 int steps = Math.max(steps1, steps2) 对比两种路径的最大步数。
    • 更新全局最大值 res

代码

public class Main {
    //要求可移动的最大次数
    public static int[][] dir ={{0,1},{1,0},{-1,0},{0,-1}};
    public static int dfs(int x,int y,int[][] a,int[][] visited,int upOrDown,int m,int n){
        //1代表上坡过来的,0代表下坡过来的
        visited[x][y]=1;
        int res=0;
        for(int i=0;i<4;++i){
            int nx = x+dir[i][0];
            int ny = y+dir[i][1];
            if(nx<0||nx>=m||ny<0||ny>=n){
                continue;
            }
            if(visited[nx][ny]==1){
                continue;
            }
            if(a[nx][ny]==a[x][y]){
                continue;
            }
            if(upOrDown==1&&a[nx][ny]>a[x][y]){
                continue;
            }
            if(upOrDown==0&&a[nx][ny]<a[x][y]){
                continue;
            }
            res=Math.max(res,1+dfs(nx, ny, a, visited, 1-upOrDown, m, n));
        }
        visited[x][y]=0;
        return res;
    }
    public static int solution(int m, int n, int[][] a) {
        // write code here
        //每个位置作为起始点走一遍
        int res=0;
        int[][] visited = new int[m][n];
        for(int i=0;i<m;++i){
            for(int j=0;j<n;++j){
                int steps1 = dfs(i,j,a,visited,0,m,n);
                int steps2 = dfs(i,j,a,visited,1,m,n);
                int steps=Math.max(steps1,steps2);
                res=Math.max(steps,res);
            }
        }
        return res;
    }
}

算法复杂度

时间复杂度:O(n2×m2n^2 \times m^2),外层是n×mn \times m的for循环,dfs最坏时间复杂度也是n×mn \times m,这个时间复杂度是相当大的,其实可以利用记忆化搜索优化一下,但是我这一块记忆化没有写好,存在问题,就没有在这篇文章进行讨论了。

空间复杂度:O(n×mn \times m),创建了visted数组,以及最多存在n×mn \times m次递归栈调用。