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

211 阅读2分钟

问题文本

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

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

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

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

1 2
4 3

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

问题分析

该问题可以用深度搜索方法解决。我们从某一点(x,y)开始执行深度搜索算法,当小U到达某一点时,其需要查询周围点是否运行行走,对每一个允许的点步数+1并继续执行深度搜索算法,而如果四个点都无法满足要求便返回当前步数。

小U的每一次行走方向都会被上一次行走的高低变化限制:

  1. 当小U走第一步时,小U可以走上坡或下坡
  2. 当小U走非第一步时,小U需要和上一次行走的高度差正好相反

所以我们可以使用变量direction表示上一次行走的方向,+1表示走上坡,-1表示走下坡,0表示出发。判断某一点是否可走可以通过以下函数判断

def allowWalk(tryX, tryY): 
        return not hasVisted[tryX][tryY] and (currentHight - a[tryX][tryY]) * direction > 0

tryX、tryY表示尝试的点,currentHight则表示当前的点。

在深度搜索算法的实现方式上有递归和迭代两种方式,我们本次选用递归方式,代码实现如下:

def solution(m: int, n: int, a: list) -> int:
    maxStep = 0
    hasVisted = [[False] * n for _ in range(m)]
    for x in range(m):
        for y in range(n):
            maxStep = max(maxStep, deepSearch(x, y, a, hasVisted, -1, m, n), deepSearch(x, y, a, hasVisted, 1, m, n))
    return maxStep - 1


def deepSearch(x, y, a, hasVisted, direction, m, n):
    ret = 0
    hasVisted[x][y] = True
    currentHight = a[x][y]

    def allowWalk(tryX, tryY): 
        return not hasVisted[tryX][tryY] and (currentHight - a[tryX][tryY]) * direction > 0

    if x - 1 >= 0 and allowWalk(x-1, y):
        ret = max(ret, deepSearch(
            x-1, y, a, hasVisted, -direction, m, n))
    if x + 1 < m and allowWalk(x+1, y):
        ret = max(ret, deepSearch(
            x+1, y, a, hasVisted, -direction, m, n))
    if y - 1 >= 0 and allowWalk(x, y-1):
        ret = max(ret, deepSearch(
            x, y-1, a, hasVisted, -direction, m, n))
    if y + 1 < n and allowWalk(x, y+1):
        ret = max(ret, deepSearch(
            x, y+1, a, hasVisted, -direction, m, n))
    hasVisted[x][y] = False
    return ret + 1