问题描述
小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:
- 只能上坡或者下坡,不能走到高度相同的点。
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
- 每个位置只能经过一次,不能重复行走。
任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。
问题分析
容易想到是dfs的做法,遍历每一个坐标出发,对四个方向进行深度搜索,同时维护一个矩阵记录是否走过。 递归逻辑:
- 传入下次行走是上坡还是下坡,对当前坐标标记为走过,更新当前长度
- 对四个方向的相邻坐标,如果目标坐标在正确范围内且未被走过且符合行走逻辑(一次上坡一次下坡),则进入
- 返回处记录最大值并记录。
值得注意的是,在第一次递归的时候需要上坡策略和下坡策略都进行尝试并记录。
tmp_len1 = dfs(i, j, False, 0) tmp_len2 = dfs(i, j, True, 0)
代码
def solution(m: int, n: int, a: list) -> int:
# write code here
visited = [[False] * n for _ in range(m)]
# 定义DFS函数
def dfs(x, y, is_up, current_length):
# 标记当前位置为已访问
visited[x][y] = True
# 更新当前路径长度
current_length += 1
# 定义四个方向的偏移量
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 初始化最大路径长度
max_length = current_length
# 遍历四个方向
for i in range(4):
nx, ny = x + dx[i], y + dy[i]
# 检查新位置是否在地图范围内
if 0 <= nx < m and 0 <= ny < n:
# 检查新位置是否未被访问过
if not visited[nx][ny]:
# 检查是否满足交替移动的条件
if (is_up and a[nx][ny] < a[x][y]) or (not is_up and a[nx][ny] > a[x][y]):
# 递归调用DFS
max_length = max(max_length, dfs(nx, ny, not is_up, current_length))
# 回溯:标记当前位置为未访问
visited[x][y] = False
return max_length
# 初始化最大路径长度
max_length = 0
# 遍历每个位置,进行DFS
for i in range(m):
for j in range(n):
# 从每个未访问的位置开始DFS
tmp_len1 = dfs(i, j, False, 0)
tmp_len2 = dfs(i, j, True, 0)
tmp_lem = max(tmp_len1,tmp_len2)
max_length = max(max_length, tmp_lem-1)
# print(i,j, tmp_lem)
return max_length