返回

算法盛宴:LeetCode Weekly Contest 271 精彩题解,陪你上岸!

闲谈

环和杆:

环形操场上有 N 个杆子,每个杆子上都有一个旗帜。现在需要把这些旗帜沿着顺时针方向移动到相邻的杆子上,使得每个杆子上都有一个旗帜。问最少需要多少次移动才能完成任务?

子数组范围和:

给定一个长度为 n 的数组 nums,以及一个整数 k,请你找到数组中所有长度为 k 的连续子数组的范围和。

给植物浇水 II:

你有一块长方形的花园,花园里种有 n 棵植物,每棵植物都需要每天浇水。花园里有一个水龙头,每天可以从水龙头里接水浇灌花园里的所有植物。但是,水龙头里的水量有限,每天只能接一定量的水。现在,你需要制定一个浇水方案,使得所有植物每天都能得到足够的水,且水龙头的总用水量最少。

摘水果:

在一个农场里,有 m 行 n 列的水果树,每棵树上都结有不同的水果。现在,你要从起始点 (startPos.row, startPos.col) 开始摘水果,并沿着四个方向(上、下、左、右)不断前进,直到走出农场。在前进过程中,你可以选择摘取任意一棵树上的水果,但只能摘一次。请你设计一个策略,使得你能摘到最多的水果。

精彩点评:
本次 LeetCode Weekly Contest 271 题目设计精巧,涵盖了多种算法技巧,从基础的遍历到复杂的动态规划,为参赛者们提供了一次全面的算法挑战。环和杆作为签到题,难度适中,是入门算法竞赛的绝佳选择。子数组范围和和给植物浇水 II 都需要利用动态规划的思想来解决,考验参赛者对算法技巧的掌握程度。摘水果则是一道烧脑的难题,需要参赛者仔细分析题意,并设计出最优的策略才能获得高分。

LeetCode Weekly Contest 271 解题代码:

# 环和杆
def min_moves_to_seat(n: int, startPos: int, endPos: int) -> int:
    """
    :type n: int
    :type startPos: int
    :type endPos: int
    :rtype: int
    """
    return min(abs(endPos - startPos), n - abs(endPos - startPos))

# 子数组范围和
def subarray_sum(nums: list[int], k: int) -> list[list[int]]:
    """
    :type nums: list[int]
    :type k: int
    :rtype: list[list[int]]
    """
    res = []
    for i in range(len(nums) - k + 1):
        sum = 0
        for j in range(k):
            sum += nums[i+j]
        res.append(sum)
    return res

# 给植物浇水 II
def min_water_cost(garden_length: int, plants: list[int], capacity: int) -> int:
    """
    :type garden_length: int
    :type plants: list[int]
    :type capacity: int
    :rtype: int
    """
    cur_pos = 0
    cur_water = capacity
    refill_cnt = 0
    for plant in plants:
        if plant > cur_water:
            refill_cnt += 1
            cur_pos = 0
            cur_water = capacity
        cur_pos = plant
        cur_water -= plant
    return refill_cnt

# 摘水果
def max_fruits(grid: list[list[int]], startPos: list[int], moves: int) -> int:
    """
    :type grid: list[list[int]]
    :type startPos: list[int]
    :type moves: int
    :rtype: int
    """
    m, n = len(grid), len(grid[0])
    max_fruits = 0
    
    def dfs(row, col, remaining_moves):
        if row < 0 or row >= m or col < 0 or col >= n or remaining_moves < 0 or grid[row][col] == 0:
            return 0
        
        grid[row][col] = 0  # 标记该位置已被访问
        
        # 探索四个方向
        up = dfs(row - 1, col, remaining_moves - 1)
        down = dfs(row + 1, col, remaining_moves - 1)
        left = dfs(row, col - 1, remaining_moves - 1)
        right = dfs(row, col + 1, remaining_moves - 1)
        
        # 计算当前位置可摘到的水果数量
        fruits = grid[row][col]
        
        # 回溯,恢复该位置的水果数量
        grid[row][col] = fruits
        
        # 返回当前位置可摘到的水果数量加上子问题中可摘到的水果数量的最大值
        return max(fruits + up, fruits + down, fruits + left, fruits + right)
    
    return dfs(startPos[0], startPos[1], moves)

结语:
LeetCode Weekly Contest 是一个非常好的算法竞赛平台,它可以帮助你提高算法技巧,并与全球的算法高手们一较高下。如果你对算法竞赛感兴趣,那么我强烈建议你参加 LeetCode Weekly Contest。