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

LeetCode 3649: Number of Perfect Pairs

·1 分鐘· ·
LeetCode Medium Two-Pointers Math Sorting Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2025-08-16

  • 提交紀錄:Accepted(一次通過)

解題思路
#

這題的關鍵是先把條件化簡。設 x = min(|a|, |b|)、y = max(|a|, |b|):

  • 不管 a、b 的正負號,{|a - b|, |a + b|} 一定是 {y - x, y + x}:同號時相減會抵消,異號時相加會抵消。
  • 第一個條件:min = y - x <= x,也就是 y <= 2x。
  • 第二個條件:max = y + x >= y,永遠成立。

所以只要數「較大的絕對值 <= 2 × 較小的絕對值」的配對數,跟原本的正負號、位置都無關。

把絕對值排序後,對每個 right,找最左邊滿足 2 * arr[left] >= arr[right] 的 left,[left, right) 裡每個都能跟 arr[right] 配對。right 變大時,left 只會往右,所以是同向雙指針。

我的解法
#

class Solution:
    def perfectPairs(self, nums: List[int]) -> int:
        arr = sorted(abs(x) for x in nums)
        ans = left = 0
        for right, y in enumerate(arr):
            while 2 * arr[left] < y:
                left += 1
            ans += right - left            # arr[left..right-1] 都能跟 y 配對
        return ans

left 最多走到 right(2y >= y),所以不會越界。

複雜度
#

時間 O(n log n),空間 O(n)。

要特別避免的錯誤
#

  • 直接照原條件 O(n^2) 枚舉:n 到 10^5 會超時。
  • 化簡時漏掉正負號的兩種情況。

面試口說整理
#

我先化簡條件:設兩個數的絕對值是 x <= y,|a - b| 和 |a + b| 一定是 y - x 和 y + x,所以第二個條件永遠成立,第一個條件變成 y <= 2x。接著把絕對值排序,對每個右端用一個只會往右走的左指針,找到第一個 2 * arr[left] >= arr[right] 的位置,中間的都能配對。時間 O(n log n)。

相關文章

LeetCode 2410: Maximum Matching of Players With Trainers
·1 分鐘
LeetCode Medium Two-Pointers Greedy Sorting Array
LeetCode 2410 解題筆記:兩邊都排序後,用同向雙指針讓最弱的球員配最小的、夠用的教練
LeetCode 3627: Maximum Median Sum of Subsequences of Size 3
·1 分鐘
LeetCode Medium Math Greedy Sorting Game-Theory Array
LeetCode 3627 解題筆記:排序後每次拿最大的兩個和最小的一個,中位數是第二大的;答案是從尾端往前每隔一個取,共 n / 3 個
LeetCode 189: Rotate Array
·1 分鐘
LeetCode Medium Array Math Two-Pointers
LeetCode 189 解題筆記:先 k %= n,再用三次反轉:整個反轉、前 k 個反轉、後 n - k 個反轉;O(1) 額外空間
LeetCode 75: Sort Colors
·1 分鐘
LeetCode Medium Array Two-Pointers Sorting Quicksort
LeetCode 75 解題筆記:荷蘭國旗:low 左邊都是 0、high 右邊都是 2;遇到 2 換到 high 之後不要前進,換過來的數還沒檢查
LeetCode 15: 3Sum
·2 分鐘
LeetCode Medium Array Two-Pointers Sorting
LeetCode 15 解題筆記:排序後固定第一個數,剩下用對撞指針找兩數和;三個位置都要跳過相同的值,才不會有重複的組合
LeetCode 16: 3Sum Closest
·1 分鐘
LeetCode Medium Array Two-Pointers Sorting
LeetCode 16 解題筆記:排序後固定一個數,對撞指針找另外兩個;比較的是和跟 target 的距離 abs(sum - target)