问题描述
小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:
- 只能上坡或者下坡,不能走到高度相同的点。
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
- 每个位置只能经过一次,不能重复行走。
任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。
例如在以下2x2的地图中:
1 2
4 3
中庸行者可以选择移动顺序 3 -> 4 -> 1 -> 2,最大移动次数为3。
测试样例
样例1:
输入:
m = 2, n = 2, a = [[1, 2], [4, 3]]
输出:3
样例2:
输入:
m = 3, n = 3, a = [[10, 1, 6], [5, 9, 3], [7, 2, 4]]
输出:8
样例3:
输入:
m = 4, n = 4, a = [[8, 3, 2, 1], [4, 7, 6, 5], [12, 11, 10, 9], [16, 15, 14, 13]]
输出:11
解题思路
此问题可以通过深度优先搜索(DFS)来解决。核心思想是从地图上的每一个位置出发,尝试所有可能的路径,并记录每一条路径的最大长度。由于每次移动都需要改变方向(从上坡变下坡或从下坡变上坡),因此在递归过程中需要传递当前的方向信息。
代码实现
def solution(m: int, n: int, a: list) -> int:
max_moves = 0
visited = set()
def dfs(x, y, visited, direction, moves):
nonlocal max_moves
# 边界检查和已访问检查
if x < 0 or x >= m or y < 0 or y >= n or (x, y) in visited:
max_moves = max(max_moves, moves)
return
current_height = a[x][y]
visited = visited | {(x, y)} # 当前位置标记为已访问
if direction == "up":
# 尝试四个方向的上坡移动
for dx, dy in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
next_x = x + dx
next_y = y + dy
if 0 <= next_x < m and 0 <= next_y < n and (next_x, next_y) not in visited:
next_height = a[next_x][next_y]
if next_height > current_height:
dfs(next_x, next_y, visited, "down", moves + 1)
elif direction == "down":
# 尝试四个方向的下坡移动
for dx, dy in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
next_x = x + dx
next_y = y + dy
if 0 <= next_x < m and 0 <= next_y < n and (next_x, next_y) not in visited:
next_height = a[next_x][next_y]
if next_height < current_height:
dfs(next_x, next_y, visited, "up", moves + 1)
max_moves = max(max_moves, moves)
return
# 从每个位置开始,分别尝试向上和向下两种初始方向
for i in range(m):
for j in range(n):
dfs(i, j, visited, "up", 0)
dfs(i, j, visited, "down", 0)
return max_moves