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

LeetCode 1782: Count Pairs Of Nodes

·2 分鐘· ·
LeetCode Hard Two-Pointers Graph Sorting Hash-Table Counting
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-01-24

  • 提交紀錄:Wrong Answer → Runtime Error ×2 → Accepted

解題思路
#

incident(a, b) = deg[a] + deg[b] - shared(a, b),shared(a, b) 是 a、b 之間的邊數(可能有重邊)。

直接枚舉所有點對是 O(n^2),太慢。拆成兩步:

  1. 先忽略 shared:數 deg[a] + deg[b] > q 的配對數。把度數排序後,用對撞指針:
    • deg[left] + deg[right] > q:left..right - 1 每一個跟 right 配都成立,加上 right - left,right 往左。
    • 否則 left 往右。
  2. 修正:只有真的相連的點對,shared > 0。對每一對相連的 (u, v),如果 deg[u] + deg[v] > q 但 deg[u] + deg[v] - shared <= q,代表第一步多算了,減 1。

相連的點對最多 E 對,所以每個查詢是 O(n + E)。

我的嘗試
#

  1. 第一版 WA:shared 的 key 直接用 (u, v),沒有把小的放前面,所以 [1, 2] 和 [2, 1] 這兩條重邊被當成兩組不同的點對,各自只有 1 條共用邊,修正量算錯。例如 n = 2、edges = [[1, 2], [2, 1]]、queries = [2]:incident(1, 2) = 2,不大於 2,答案是 [0],這版回傳 [1]。
  2. 兩次 RE:補上交換時打錯變數名稱,一次寫成 u, v(還沒定義),一次寫成 i, j = j, v。

正確解法
#

class Solution:
    def countPairs(self, n: int, edges: List[List[int]], queries: List[int]) -> List[int]:
        deg = [0] * (n + 1)
        shared = Counter()
        for u, v in edges:
            deg[u] += 1
            deg[v] += 1
            shared[(min(u, v), max(u, v))] += 1   # 重邊要合併到同一個 key

        sorted_deg = sorted(deg[1:])
        ans = []
        for q in queries:
            count = 0
            left, right = 0, n - 1
            while left < right:
                if sorted_deg[left] + sorted_deg[right] > q:
                    count += right - left
                    right -= 1
                else:
                    left += 1
            for (u, v), c in shared.items():
                if deg[u] + deg[v] > q >= deg[u] + deg[v] - c:
                    count -= 1                     # 扣掉共用邊後就不成立
            ans.append(count)
        return ans

複雜度
#

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

要特別避免的錯誤
#

  • 無向邊的 key 沒有正規化,重邊被拆成兩組。
  • 直接 O(n^2) 枚舉點對。

面試口說整理
#

incident(a, b) 等於兩點度數相加減掉它們之間的邊數。我先忽略共用邊,把度數排序後用對撞指針數度數和大於 q 的配對;再對每一對真的相連的點檢查,如果度數和大於 q、扣掉共用邊後卻不大於 q,就減一。每個查詢 O(n + E)。

相關文章

LeetCode 923: 3Sum With Multiplicity
·3 分鐘
LeetCode Medium Two-Pointers Sorting Hash-Table Counting Array
LeetCode 923 解題筆記:排序後固定第一個數、對撞指針找另外兩個;兩端值相同時用組合數一次算完,不同時把兩端各自的重複數相乘
LeetCode 3518: Smallest Palindromic Rearrangement II
·2 分鐘
LeetCode Hard Math Combinatorics Counting Hash-Table String
LeetCode 3518 解題筆記:回文由左半邊決定,變成「多重集合的第 k 個排列」;逐位試每個字元,用排列數判斷第 k 個落在哪個分支,排列數可以 O(1) 更新
LeetCode 229: Majority Element II
·1 分鐘
LeetCode Medium Array Hash-Table Sorting Counting
LeetCode 229 解題筆記:超過 n / 3 的數最多兩個;Boyer-Moore 維護兩個候選人,最後再掃一次確認次數
LeetCode 992: Subarrays with K Different Integers
·1 分鐘
LeetCode Hard Sliding-Window Hash-Table Counting Array
LeetCode 992 解題筆記:「剛好 k 種」=「最多 k 種」−「最多 k - 1 種」,「最多」型的計數視窗每個右端加 right - left + 1
LeetCode 3545: Minimum Deletions for At Most K Distinct Characters
·1 分鐘
LeetCode Easy Greedy Hash-Table String Sorting Counting
LeetCode 3545 解題筆記:要減少種類就得整種刪掉,從出現次數最少的開始刪
LeetCode 1498: Number of Subsequences That Satisfy the Given Sum Condition
·2 分鐘
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 1498 解題筆記:子序列只看最小值和最大值,排序後順序無關;固定最小值 nums[left],中間的元素任意選,共 2^(right - left) 種