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

46 阅读4分钟

问题描述

小U决定在一个 𝑚 × 𝑛 m×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

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_steps = 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_steps = max(max_steps, 1 + dfs(nx, ny, False))
            elif not is_uphill and a[nx][ny] < a[x][y]:
                max_steps = max(max_steps, 1 + dfs(nx, ny, True))
    
    # 回溯,标记当前位置为未访问
    visited[x][y] = False
    
    return max_steps

# 初始化最大步数
max_moves = 0

# 从每个位置开始尝试
for i in range(m):
    for j in range(n):
        max_moves = max(max_moves, dfs(i, j, True), dfs(i, j, False))

return max_moves

问题理解

地图和移动规则:

你有一个 m x n 的地图,每个位置都有一个高度值。 小U只能在满足以下条件的情况下移动: 只能上坡或者下坡,不能走到高度相同的点。 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。 每个位置只能经过一次,不能重复行走。

目标:

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

数据结构选择

访问标记数组: 使用一个二维数组 visited 来记录每个位置是否已经被访问过。

DFS 深度优先搜索: 使用 DFS 来探索所有可能的路径。DFS 适合这种需要遍历所有可能路径的问题。

算法步骤

初始化: 初始化一个 visited 数组,用于记录每个位置是否已经被访问过。

DFS 函数: 定义一个 DFS 函数,该函数接受当前位置 (x, y) 和当前的移动方向(上坡或下坡)作为参数。 在 DFS 函数中,标记当前位置为已访问。 尝试向四个方向(上、下、左、右)移动,检查是否满足移动条件(边界、未访问、交替上坡下坡)。 如果满足条件,递归调用 DFS 函数,并更新最大步数。 回溯时,标记当前位置为未访问。

主函数: 从每个位置开始尝试,调用 DFS 函数,并记录最大步数。

反思:为什么在DFS函数中需要回溯?

避免重复访问:

在DFS中,我们使用一个 visited 数组来记录每个位置是否已经被访问过。如果不进行回溯,一旦某个位置被标记为已访问,就无法再次访问它,这会限制我们探索其他可能的路径。 通过回溯,我们可以在探索完一条路径后,将当前位置重新标记为未访问,从而允许其他路径再次访问这个位置。

探索所有可能的路径:

回溯确保我们能够探索所有可能的路径,而不仅仅是一条路径。如果不进行回溯,DFS 只会沿着一条路径一直走到底,而不会尝试其他可能的路径。 通过回溯,我们可以在每条路径的末尾返回到上一个节点,继续探索其他方向,从而找到所有可能的路径。

总结

使用 DFS 来探索所有可能的路径。 使用 visited 数组来记录每个位置是否已经被访问过。 确保移动是交替进行的(上坡后下坡,下坡后上坡)。 从每个位置开始尝试,记录最大步数。