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

163 阅读3分钟

问题描述

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

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

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

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

1 2
4 3

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

问题理解

  1. 地图和移动规则

    • 你有一个 m x n 的地图,每个位置有一个高度值。
    • 小U只能上坡或下坡,不能走到高度相同的点。
    • 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡。
    • 每个位置只能经过一次,不能重复行走。
  2. 目标

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

数据结构选择

  • 二维数组:用于存储地图的高度值。
  • 访问标记数组:用于记录每个位置是否已经被访问过。

算法步骤

  1. 深度优先搜索 (DFS)

    • 从每个位置开始,尝试进行深度优先搜索,探索所有可能的路径。
    • 在DFS过程中,根据当前位置的高度和上一次移动的方向(上坡或下坡),决定下一步的移动方向。
  2. 交替移动

    • 在DFS中,使用一个布尔值标记当前是上坡还是下坡。
    • 根据这个标记,决定下一步的移动方向。
  3. 回溯

    • 在DFS过程中,如果某个路径无法继续前进,需要回溯到上一个位置,尝试其他可能的路径。
  4. 记录最大移动次数

    • 在DFS过程中,记录并更新最大移动次数。

总结

通过深度优先搜索和回溯,结合交替移动的规则,可以有效地探索所有可能的路径,并找到最大移动次数。

代码

def solution(m: int, n: int, a: list) -> int:
    # 初始化访问标记数组
    visited = [[False] * n for _ in range(m)]
    
    def dfs(x, y, is_uphill):
        # 标记当前位置为已访问
        visited[x][y] = True
        
        # 初始化最大移动次数
        max_moves = 0
        
        # 遍历四个方向
        for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
            nx, ny = x + dx, y + dy
            
            # 检查边界和是否已访问
            if 0 <= nx < m and 0 <= ny < n and not visited[nx][ny]:
                # 检查是否符合交替上坡下坡的规则
                if is_uphill and a[nx][ny] > a[x][y]:
                    max_moves = max(max_moves, 1 + dfs(nx, ny, False))
                elif not is_uphill and a[nx][ny] < a[x][y]:
                    max_moves = max(max_moves, 1 + dfs(nx, ny, True))
        
        # 回溯,标记当前位置为未访问
        visited[x][y] = False
        
        return max_moves
    
    # 初始化最大移动次数
    max_moves = 0
    
    # 遍历每个位置作为起点
    for i in range(m):
        for j in range(n):
            max_moves = max(max_moves, dfs(i, j, True))
            max_moves = max(max_moves, dfs(i, j, False))
    
    return max_moves