刷题18 | 豆包MarsCode AI刷题

101 阅读2分钟

问题描述

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

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

任务是帮助小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