小U的最大连续移动次数问题(刷题笔记)
问题描述
问题描述
小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:
- 只能上坡或者下坡,不能走到高度相同的点。
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
- 每个位置只能经过一次,不能重复行走。
任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。
例如在以下2x2的地图中:
1 2
4 3
中庸行者可以选择移动顺序 3 -> 4 -> 1 -> 2,最大移动次数为3。
解题思路
1.创建一个布尔数组visited记录每个位置的访问情况 2.DFS深度搜索:根据当前位置和先前位置决定上坡和下坡,用递归实现
代码
public class Main {
public static int solution(int m, int n, int[][] a) {
// write code here
boolean[][] visited = new boolean[m][n];
int maxMoves = 0;
if (m == 1 && n == 1) {
return 0;
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
maxMoves = Math.max(maxMoves, DFS(i, j, a, visited, 0, true) - 1);
maxMoves = Math.max(maxMoves,DFS(i, j, a, visited,Integer.MAX_VALUE, false)-1);
}
}
System.out.println(maxMoves);
return maxMoves ;
}
public static int DFS(int x, int y, int[][] a, boolean[][] visited, int pHeight, boolean isUp) {
int cHeight = a[x][y];
if (x < 0 || x >= a.length || y < 0 || y >= a[0].length || visited[x][y] || cHeight == pHeight) {
return 0;
}
visited[x][y] = true;
int moves = 0;
// System.out.println("Visiting (" + x + ", " + y + ") with height " + cHeight);
int[][] directions = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
for (int[] direction : directions) {
int nextX = x + direction[0];
int nextY = y + direction[1];
boolean b = !(nextX >= a.length || nextX < 0 || nextY >= a[0].length || nextY < 0);
if (isUp && cHeight > pHeight) {
if (b ) {
moves = Math.max(moves, 1 + DFS(nextX, nextY, a, visited, cHeight, false));
}
} else if (!isUp && cHeight < pHeight) {
if (b ) {
moves = Math.max(moves, 1 + DFS(nextX, nextY, a, visited, cHeight, true));
}
}
}
visited[x][y] = false;
return moves;
}
public static void main(String[] args) {
System.out.println(solution(2, 2, new int[][] { { 1, 2 }, { 4, 3 } }) == 3);
System.out.println(solution(3, 3, new int[][] { { 10, 1, 6 }, { 5, 9, 3 }, { 7, 2, 4 } }) == 8);
System.out.println(solution(4, 4,
new int[][] { { 8, 3, 2, 1 }, { 4, 7, 6, 5 }, { 12, 11, 10, 9 }, { 16, 15, 14, 13 } }) == 11);
}
}
总结
1.遇到给定地图的二维数组,可以联想到DFS或BFS的遍历方式 2. DFS的递归调用:在DFS中,根据当前位置的高度和前一个位置的高度,决定下一步是上坡还是下坡。 3. 回溯:在DFS结束后,需要将当前位置标记为未访问,以便其他路径可以再次访问该位置。 4. 边界条件:在DFS中,需要检查下一个位置是否在地图范围内,并且不能重复访问同一个位置。