↓快轉到主要內容
  1. LeetCode/

LeetCode 3873: Maximum Points Activated with One Addition

·1 分鐘· ·
LeetCode Hard Union-Find Hash-Table Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-07-29

  • 提交紀錄:Time Limit Exceeded → Wrong Answer → Accepted ×2

解題思路
#

啟動會沿著「同 x 或同 y」一直傳下去,所以一個點被啟動,它所在的整塊都會被啟動。先用 Union-Find 把點分成塊。

新加的點 (x, y) 只能透過它的 x 接上一塊、透過它的 y 接上一塊,最多兩塊。挑最大的兩塊 A、B:x 取 A 裡某個點的 x,y 取 B 裡某個點的 y。這個座標一定沒有點,因為如果有,它會同時跟 A、B 相連,A 和 B 就是同一塊了。只有一塊時就是那塊加 1。

合併時不要兩兩比較,用字典記每個 x(和每個 y)第一次出現的點,之後的點跟它合併(Union-Find 的「用第一個出現的代表合併」)。

我的嘗試
#

  1. 第一版兩兩比較所有點,O(n²),TLE。
  2. 第二版把同 x、同 y 的點收集到集合裡,但合併時寫成 union(i - 1, i),用的是迴圈的 index,不是集合裡的點。例如 [[0, 0], [1, 2], [3, 3], [3, 0]]:(0, 0)、(3, 0)、(3, 3) 是一塊,加上 (1, 2) 那一塊,答案是 5,這版回傳 4。
  3. 改成合併集合裡的元素就 AC 了;再改成用字典記第一個出現的點,更快。

正確解法
#

class Solution:
    def maxActivated(self, points: List[List[int]]) -> int:
        n = len(points)
        parent = list(range(n))

        def find(x):
            while parent[x] != x:
                parent[x] = parent[parent[x]]
                x = parent[x]
            return x

        first_x, first_y = {}, {}
        for i, (x, y) in enumerate(points):
            for first, key in ((first_x, x), (first_y, y)):
                if key in first:
                    parent[find(i)] = find(first[key])
                else:
                    first[key] = i
        sizes = sorted(Counter(find(i) for i in range(n)).values(), reverse=True)
        return sum(sizes[:2]) + 1

複雜度
#

時間 O(n · α(n) + n log n),空間 O(n)。

要特別避免的錯誤
#

  • 不要兩兩比較,用字典記代表點。
  • 合併的是集合裡的元素,不是迴圈的 index。

面試口說整理
#

啟動會傳遍整個連通塊,所以我先用 Union-Find 把同 x 或同 y 的點合併,合併時用字典記每個座標第一次出現的點。新點最多透過 x 接一塊、透過 y 接一塊,而且挑兩個不同塊的 x、y 組出來的位置一定是空的,所以答案是最大的兩塊加 1。時間 O(n log n)。

相關文章

LeetCode 952: Largest Component Size by Common Factor
·2 分鐘
LeetCode Hard Math Number-Theory Union-Find Hash-Table Array
LeetCode 952 解題筆記:有共同因數 ⇔ 有共同的質因數;把每個數分解質因數,同一個質因數的 index 用 Union-Find 合併,不用兩兩算 GCD
LeetCode 2382: Maximum Segment Sum After Removals
·1 分鐘
LeetCode Hard Union-Find Prefix-Sum Ordered-Set Array
LeetCode 2382 解題筆記:倒著做,把刪除變成加回去;Union-Find 的根記區段總和,最大值只會變大
LeetCode 41: First Missing Positive
·2 分鐘
LeetCode Hard Hash-Table Array
LeetCode 41 解題筆記:答案一定在 1..n+1;把不可能的值換成 n+1(不能用 0),用 nums[v-1] 的負號標記 v 出現過
LeetCode 2122: Recover the Original Array
·2 分鐘
LeetCode Hard Two-Pointers Sorting Hash-Table Enumeration Array
LeetCode 2122 解題筆記:最小的數一定在 lower,枚舉它的配對決定 k;排序後用兩個指針把每個最小的未配對數配給 +2k 的數
LeetCode 2009: Minimum Number of Operations to Make Array Continuous
·1 分鐘
LeetCode Hard Sliding-Window Hash-Table Binary-Search Array
LeetCode 2009 解題筆記:最後的陣列是長度 n 的連續整數;去重排序後,用滑動視窗找值域寬度 <= n - 1 的最多不同值,其他都要改
LeetCode 2709: Greatest Common Divisor Traversal
·2 分鐘
LeetCode Hard Math Number-Theory Union-Find Sieve Gcd Array
LeetCode 2709 解題筆記:任兩個 index 都能互通 ⇔ 全部在同一個連通塊;用 SPF 分解質因數,數字跟它的質因數在 Union-Find 裡合併;1 要特別處理