返回

LeetCode每日一题:发现局部最优,征服天际线挑战

闲谈

贪心算法的智慧:局部最优与全局最优

面对“保持城市天际线”的难题,我们首先需要理解贪心算法的精髓。贪心算法是一种求解问题的策略,它通过在每一步中做出局部最优的选择,逐步逼近全局最优解。

在这个问题中,局部最优的选择就是让每行和每列的建筑物高度最大化。我们知道,天际线的高度由各个建筑物的最高点决定,因此,如果我们在每个位置都取得最大增加高度,那么整个天际线的高度就会最大化。

算法步骤:分解问题,逐步构建解决方案

  1. 计算每行和每列的最大值:

    首先,我们需要计算出网格grid中每行和每列的最大值。我们可以使用两个辅助数组cross和vec分别存储每行和每列的最大值。

def calculate_max_values(grid):
    """
    计算每行和每列的最大值

    参数:
        grid: 给定的二维网格

    返回:
        cross: 每行最大值的数组
        vec: 每列最大值的数组
    """

    # 初始化cross和vec数组
    cross = [0] * len(grid)
    vec = [0] * len(grid[0])

    # 计算每行最大值
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            cross[i] = max(cross[i], grid[i][j])

    # 计算每列最大值
    for j in range(len(grid[0])):
        for i in range(len(grid)):
            vec[j] = max(vec[j], grid[i][j])

    return cross, vec
  1. 构建天际线:

    有了每行和每列的最大值,我们就可以构建天际线了。我们将从最左上角开始,依次遍历网格中的每个位置。如果当前位置的建筑物高度大于等于所在行和列的最大值,那么这个建筑物就是天际线的一部分。

def build_skyline(grid, cross, vec):
    """
    构建天际线

    参数:
        grid: 给定的二维网格
        cross: 每行最大值的数组
        vec: 每列最大值的数组

    返回:
        skyline: 天际线的高度数组
    """

    # 初始化天际线数组
    skyline = []

    # 从最左上角开始遍历网格
    i = 0
    j = 0

    # 循环遍历网格
    while i < len(grid) and j < len(grid[0]):

        # 如果当前位置的建筑物高度大于等于所在行和列的最大值
        if grid[i][j] >= cross[i] and grid[i][j] >= vec[j]:

            # 将当前位置的高度添加到天际线数组
            skyline.append(grid[i][j])

            # 移动到下一个位置
            i += 1
            j += 1

        # 如果当前位置的建筑物高度小于所在行或列的最大值
        else:

            # 移动到下一个位置
            if cross[i] > vec[j]:
                i += 1
            else:
                j += 1

    return skyline

示例代码:亲身体验算法魅力

# 示例输入
grid = [
    [3, 0, 8, 4],
    [2, 4, 5, 7],
    [9, 2, 6, 3],
    [0, 3, 1, 0]
]

# 计算每行和每列的最大值
cross, vec = calculate_max_values(grid)

# 构建天际线
skyline = build_skyline(grid, cross, vec)

# 打印天际线
print(skyline)  # 输出:[3, 7, 9, 7, 6, 3]

总结:发现局部最优,征服全局挑战

通过对贪心算法的深入理解和具体步骤的讲解,我们成功征服了LeetCode每日一题中的“保持城市天际线”难题。通过发现局部最优解,逐步构建解决方案,我们找到了使城市总增加高度最大的方案。这道题不仅考验了我们的算法设计能力,也启发了我们对贪心算法的深入思考。在今后的编程之旅中,让我们继续探索贪心算法的奥秘,发现更多令人惊叹的解决方案。