返回

LeetCode 947:优化扫雷技巧,最大化移除石头数

前端

在编程世界的惊涛骇浪中,算法挑战犹如一个个无畏的风暴,锤炼着代码勇士们的智慧与胆识。LeetCode 947 题便是这样一场考验,它向算法高手们发出了移除石头的号角,一场场精彩的对局就此拉开序幕。

题意解析

想象一个广阔的二维棋盘,棋盘上散落着 n 块石头,每一块石头占据一个唯一的坐标点。棋盘中每个坐标点只能容纳一块石头,且不会出现两块石头占据同一坐标的情况。

当一块石头与另外一块石头处于同一行或同一列时,这块石头便可被移除。题目要求我们找出移除最多石头的策略,即最大化可移除石头的数量。

破题之道

解开这道难题的关键在于巧妙地利用石头之间的位置关系。我们从一个简单的观察入手:如果两块石头处于同一行或同一列,那么其中一块必定可以被移除。

基于此,我们可以将问题分解为两步:

  1. 识别可移除的石头: 首先,遍历棋盘上的所有石头,找出可以被移除的石头。这些石头要么处于同一行,要么处于同一列。
  2. 最大化可移除石头数: 识别出可移除的石头后,我们需要最大化可移除石头的数量。这可以通过以下策略实现:
    • 优先移除可以同时移除多块石头的石头。例如,如果一行或一列有多块石头,移除该行或该列上的石头可以同时移除多块石头。
    • 如果存在多组可移除的石头,选择移除可以同时移除更多石头的组。

算法实现

根据上述策略,我们可以设计一个贪心算法来解决这个问题:

def remove_stones(stones):
    """
    :type stones: List[List[int]]
    :rtype: int
    """
    # 存储可以被移除的石头
    removable_stones = set()

    # 遍历所有石头,找出可以被移除的石头
    for stone in stones:
        x, y = stone
        for other_stone in stones:
            if x == other_stone[0] or y == other_stone[1]:
                removable_stones.add(stone)
                removable_stones.add(other_stone)

    # 最大化可移除石头数
    max_removable_stones = 0
    while removable_stones:
        # 从可移除的石头中选择一组可以同时移除最多石头的石头
        removable_group = set()
        for stone in removable_stones:
            x, y = stone
            for other_stone in stones:
                if x == other_stone[0] or y == other_stone[1]:
                    removable_group.add(other_stone)
        
        # 移除这组石头
        removable_stones -= removable_group
        max_removable_stones += len(removable_group)

    return max_removable_stones

复杂度分析

  • 时间复杂度: O(n^2),其中 n 是石头数量。算法需要遍历所有石头,并检查每对石头之间的关系。
  • 空间复杂度: O(n),用于存储可移除的石头。

结语

LeetCode 947 题是一道考验算法技能和思维敏捷度的挑战。通过巧妙地利用石头之间的位置关系,我们设计了一个贪心算法来最大化可移除石头的数量。这种方法不仅高效,而且简洁明了,彰显了算法之美。