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

LeetCode 825: Friends Of Appropriate Ages

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

基本資料
#

難易度: medium 第一次嘗試:2026-01-21

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

解題思路
#

x 會送邀請給 y 的條件,整理後是:

  • age[y] > 0.5 * age[x] + 7
  • age[y] <= age[x]
  • 第三個條件(age[y] > 100 and age[x] < 100)在 age[y] <= age[x] 時不可能成立,可以忽略。

所以對年齡 a 的人,能邀請的對象是年齡落在 (0.5a + 7, a] 的人,再扣掉自己。

排序後,這是一段連續區間 [left, right)。依年齡由小到大處理每個人時,區間的兩端都只會往右,用兩個同向指針維護:

  • left:跳過所有 <= 0.5a + 7 的人。
  • right:吃進所有 <= a 的人(同齡的人也要算進來)。

區間不是空的時候,自己一定在裡面(a > 0.5a + 7 才可能有人),所以加上 right - left - 1。

我的嘗試
#

版本問題
第一、二版 WA用「right 往右走、只數 right 左邊的人」的方式,同齡的人只有一個方向被算到,再用「每種重複年齡加 1」補,數量不對。例如 [16, 16, 16]:三個人互相邀請,答案是 6,這兩版都回傳 4
第三版 RE改成兩個指針,但門檻寫成 0.5 * ages[right] + 7,right 走到 n 時越界。例如 [20, 20] 直接 IndexError
第四、五版 WA門檻改用 ages[i],但 left 的迴圈條件是 left < right,太年輕的人沒被跳完。例如 [5, 5]:5 歲的門檻是 9.5,沒有人能被邀請,答案是 0,這版回傳 1

把 left 的條件改成 left < n 就 AC 了。

正確解法
#

class Solution:
    def numFriendRequests(self, ages: List[int]) -> int:
        ages.sort()
        n = len(ages)
        ans = left = right = 0
        for age in ages:
            while left < n and ages[left] <= 0.5 * age + 7:
                left += 1                          # 太年輕的人
            while right < n and ages[right] <= age:
                right += 1                         # 不比自己大的人
            if right > left:
                ans += right - left - 1            # 扣掉自己
        return ans

另一種做法是年齡只有 1 到 120,可以用計數陣列 O(120^2) 枚舉年齡對。

複雜度
#

時間 O(n log n),空間 O(1)(不算排序)。

要特別避免的錯誤
#

  • 同齡的人互相邀請,要兩個方向都算。
  • 指針的邊界條件用 left < right:太年輕的人可能沒被跳完。
  • 區間不是空的才扣掉自己。

面試口說整理
#

整理條件後,年齡 a 的人能邀請年齡在 (0.5a + 7, a] 的人,第三個條件被第二個條件涵蓋。我把年齡排序,依序處理每個人,這段區間的兩端都只會往右,所以用兩個同向指針維護,區間大小扣掉自己就是這個人送出的邀請數。時間 O(n log n)。

相關文章

LeetCode 3413: Maximum Coins From K Consecutive Bags
·2 分鐘
LeetCode Medium Sliding-Window Greedy Sorting Prefix-Sum Binary-Search Array
LeetCode 3413 解題筆記:最佳的 k 個袋子,一定有一端對齊某段的端點;分別算「左端對齊段的起點」和「右端對齊段的終點」(鏡像後重用同一個函式)
LeetCode 2779: Maximum Beauty of an Array After Applying Operation
·1 分鐘
LeetCode Medium Sliding-Window Sorting Binary-Search Array
LeetCode 2779 解題筆記:每個數可以變成 [x - k, x + k] 裡的任何值,一群數能變成同一個值 ⇔ 最大 - 最小 <= 2k;排序後找最長的這種視窗
LeetCode 611: Valid Triangle Number
·1 分鐘
LeetCode Medium Array Two-Pointers Binary-Search Greedy
LeetCode 611 解題筆記:排序後固定最長邊 k,左右指針找兩短邊:和夠大時中間的都可以,一次加 j - i 個
LeetCode 287: Find the Duplicate Number
·1 分鐘
LeetCode Medium Array Two-Pointers Binary-Search Bit-Manipulation
LeetCode 287 解題筆記:把 i -> nums[i] 看成鏈結串列,重複的值就是環的入口,用 Floyd 判圈;O(1) 空間、不改陣列
LeetCode 167: Two Sum II - Input Array Is Sorted
·1 分鐘
LeetCode Medium Array Two-Pointers Binary-Search
LeetCode 167 解題筆記:已排序,左右指針往中間走:和太大右指針左移,太小左指針右移;回傳的 index 從 1 開始
LeetCode 75: Sort Colors
·1 分鐘
LeetCode Medium Array Two-Pointers Sorting Quicksort
LeetCode 75 解題筆記:荷蘭國旗:low 左邊都是 0、high 右邊都是 2;遇到 2 換到 high 之後不要前進,換過來的數還沒檢查