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

203 阅读3分钟

问题描述

小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:

  1. 只能上坡或者下坡,不能走到高度相同的点。
  2. 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
  3. 每个位置只能经过一次,不能重复行走。

任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。

例如在以下2x2的地图中:

1 2
4 3

中庸行者可以选择移动顺序 3 -> 4 -> 1 -> 2,最大移动次数为3。


解决方案

我们使用深度优先搜索(DFS)来遍历地图,从每个位置开始尝试不同的路径,记录最大步数。


public class Main {
 
    private static final int[][] dirs = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };

    public static int solution(int m, int n, int[][] a) {
      
        boolean[][] visited = new boolean[m][n];

      
        class DFS {
            int dfs(int x, int y, int sta) {
                int maxLength = 0;
                for (int[] dir : dirs) {
                    int nx = x + dir[0], ny = y + dir[1];

                    if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny]) {
                      
                        if (sta == 0 && a[nx][ny] > a[x][y]) {
                            visited[nx][ny] = true;
                            maxLength = Math.max(maxLength, 1 + dfs(nx, ny, 1)); downhill state
                            visited[nx][ny] = false;
                        }
                       
                        else if (sta == 1 && a[nx][ny] < a[x][y]) {
                            visited[nx][ny] = true;
                            maxLength = Math.max(maxLength, 1 + dfs(nx, ny, 0));
                            visited[nx][ny] = false;
                        }
                    }
                }
                return maxLength;
            }
        }

        int maxSteps = 0;
        DFS dfs = new DFS();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                visited[i][j] = true;
                maxSteps = Math.max(maxSteps, dfs.dfs(i, j, 0)); 
                maxSteps = Math.max(maxSteps, dfs.dfs(i, j, 1)); 
                visited[i][j] = false;
            }
        }

        return maxSteps;
    }

}

详细解释

  1. 方向数组:dirs定义了四个方向(右、下、左、上),用于在地图上移动。

dirs是一个二维数组,包含了四个可能的移动方向:右([1, 0])、下([0, 1])、左([-1, 0])和上([0, -1])。这些方向将用于在地图上进行移动操作。

  1. DFS类:内部类DFS包含一个递归方法dfs,用于执行深度优先搜索。
  • dfs方法:

    参数:接受当前坐标 (x, y) 和状态 sta(0表示上坡,1表示下坡)。 maxLength:记录从当前点出发的最长路径长度。 for循环:遍历四个方向,计算新坐标 nx 和 ny。 有效性检查:确保新坐标在地图范围内且未被访问过。 状态转换:根据当前状态 sta,判断是否可以移动到新坐标,并切换状态。 递归调用:继续从新坐标递归搜索,更新最大步数。 恢复状态:递归调用后,恢复 visited 数组的状态。

  1. 主逻辑:

maxSteps:记录整个二维数组中的最长路径长度。 遍历每个点:从每个点出发,分别以 上坡sta=0)和 下坡sta=1)的状态开始搜索最长路径。 更新maxSteps:每次搜索后,更新全局最大步数。 恢复状态:在每次搜索后恢复 visited 数组的状态。

  1. 测试用例:

main方法:定义了几个测试用例,并调用 solution 方法验证结果。

   样例1:地图大小为2x2,最大移动次数为3。
   样例2:地图大小为3x3,最大移动次数为8。
   样例3:地图大小为4x4,最大移动次数为11。

总结

我们在这里使用深度优先搜索(DFS)遍历地图,从每个点出发尝试不同的路径,寻找满足条件的最长路径。通过递归方式不断探索新的坐标,并根据当前状态(上坡或下坡)判断是否可以移动到下一个位置。最终返回所有可能路径中的最大步数。这种方法有效地解决了小U在地图上移动的问题,并通过多个测试用例验证了其正确性和有效性。