1679. Max Number of K-Sum Pairs

練習日期:2026-01-28

難度:Medium

類型:Array、Hash Table、Two Pointers、Sorting

📘 題目敘述

給定一個整數陣列 nums 與一個整數 k

你每次可以選擇 兩個數(必須是不同索引),且它們的總和剛好等於 k,然後把這兩個數從陣列中移除。

請回傳你最多可以做幾次這樣的操作(也就是最多能移除幾組「和為 k」的配對)。

條件限制

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^9
  • 1 <= k <= 10^9

🧠 解題思路

我的做法是:

  1. 先排序 nums(讓大小有順序)
  2. 用兩個指標:
    • l 指向最左邊(最小值)
    • r 指向最右邊(最大值)
  3. 每次看 nums[l] + nums[r]k 的關係來決定怎麼移動指標:
  • 如果剛好等於 k:找到一組配對,count++,然後 l++r--
  • 如果大於 k:代表右邊太大,r--
  • 如果小於 k:代表左邊太小,l++

另外我在一開始多做了一步:

  • 因為 nums[i] 都是正數,如果 nums[r] > k,那它不可能跟任何正數加出 k
  • 所以可以先把 r 往左移到 nums[r] <= k 的位置,減少後續判斷範圍

所有變數

  • nums:輸入陣列(我會先排序)
  • k:目標和
  • l:左指標(從小的開始)
  • r:右指標(從大的開始)
  • count:目前找到的合法配對數量(答案)

🪜 主要流程步驟

1. 排序

  • 排序後才能用「左右夾逼」快速判斷目前和是太大還太小

2. 先把不可能用到的右端排除(我的小優化)

  • nums[r] > k 時:
  • 因為所有數都是正數,所以 nums[l] + nums[r] >= nums[r] > k
  • 代表 nums[r] 不可能出現在任何合法配對中
  • 所以我先做:
  • 一直 r-- 直到 nums[r] <= k(或 r 到最左邊)

3. 兩指標掃描找配對

只要 l < r,就重複:

  • 情況一:nums[l] + nums[r] == k
    • 找到一組配對,可以「移除」兩個數
    • count++,並且兩邊都往內縮:l++r--
  • 情況二:nums[l] + nums[r] > k
    • 和太大,代表右邊數字太大
    • r-- 嘗試用更小的右邊數字
  • 情況三:nums[l] + nums[r] < k
    • 和太小,代表左邊數字太小
    • l++ 嘗試用更大的左邊數字

最後 count 就是最多可以取到的配對數量。

💻 程式碼實作

class Solution {
public:
    int maxOperations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int l = 0, r = nums.size() - 1;
        int count = 0;

        while (nums[r] > k && r > 0) {
            r--;
        }

        while (l < r) {
            if (nums[l] + nums[r] == k) {
                count++;
                l++;
                r--;
            } else if (nums[l] + nums[r] > k) {
                r--;
            } else {
                l++;
            }
        }
        return count;
    }
};

https://leetcode.com/problems/max-number-of-k-sum-pairs/

作者: scottnick
撰寫日期: 2026-01-28
類別:
原文連結: https://scottnick.github.io/cpp-notes/leetcode75/1679-max-number-of-k-sum-pairs.html