问题描述
小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:
- 只能上坡或者下坡,不能走到高度相同的点。
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
- 每个位置只能经过一次,不能重复行走。
任务是帮助小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;
}
}
详细解释
- 方向数组:
dirs定义了四个方向(右、下、左、上),用于在地图上移动。
dirs是一个二维数组,包含了四个可能的移动方向:右([1, 0])、下([0, 1])、左([-1, 0])和上([0, -1])。这些方向将用于在地图上进行移动操作。
- DFS类:内部类DFS包含一个递归方法
dfs,用于执行深度优先搜索。
-
dfs方法:参数:接受当前坐标
(x, y)和状态sta(0表示上坡,1表示下坡)。 maxLength:记录从当前点出发的最长路径长度。 for循环:遍历四个方向,计算新坐标nx和ny。 有效性检查:确保新坐标在地图范围内且未被访问过。 状态转换:根据当前状态sta,判断是否可以移动到新坐标,并切换状态。 递归调用:继续从新坐标递归搜索,更新最大步数。 恢复状态:递归调用后,恢复visited数组的状态。
- 主逻辑:
maxSteps:记录整个二维数组中的最长路径长度。
遍历每个点:从每个点出发,分别以 上坡(sta=0)和 下坡(sta=1)的状态开始搜索最长路径。
更新maxSteps:每次搜索后,更新全局最大步数。
恢复状态:在每次搜索后恢复 visited 数组的状态。
- 测试用例:
main方法:定义了几个测试用例,并调用 solution 方法验证结果。
样例1:地图大小为2x2,最大移动次数为3。
样例2:地图大小为3x3,最大移动次数为8。
样例3:地图大小为4x4,最大移动次数为11。
总结
我们在这里使用深度优先搜索(DFS)遍历地图,从每个点出发尝试不同的路径,寻找满足条件的最长路径。通过递归方式不断探索新的坐标,并根据当前状态(上坡或下坡)判断是否可以移动到下一个位置。最终返回所有可能路径中的最大步数。这种方法有效地解决了小U在地图上移动的问题,并通过多个测试用例验证了其正确性和有效性。