Leetcode 74 K 和数对的最大数目

1 题目

1679. K 和数对的最大数目

给你一个整数数组 nums 和一个整数 k

每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。

返回你可以对数组执行的最大操作数。

示例 1:

复制代码
输入:nums = [1,2,3,4], k = 5
输出:2
解释:开始时 nums = [1,2,3,4]:
- 移出 1 和 4 ,之后 nums = [2,3]
- 移出 2 和 3 ,之后 nums = []
不再有和为 5 的数对,因此最多执行 2 次操作。

示例 2:

复制代码
输入:nums = [3,1,3,4,3], k = 6
输出:1
解释:开始时 nums = [3,1,3,4,3]:
- 移出前两个 3 ,之后nums = [1,4,3]
不再有和为 6 的数对,因此最多执行 1 次操作。

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109

2 代码实现

cpp 复制代码
class Solution {
public:
    int maxOperations(vector<int>& nums, int k) {
        sort(nums.begin() , nums.end());
        int left = 0 ;
        int right = nums.size() - 1 ;
        int count = 0 ;
        while (left < right){
            int sum = nums[left] + nums[right] ;
            if (sum == k ){
                count ++;
                left ++ ;
                right --;
            }else if (sum < k ){
                left ++;
            }else {
                right -- ;
            }
        }
        return count ;
    }
};

题解

双指针法的核心代码模板 可以总结为「排序 + 左右指针相向移动 」,针对这道题,我给你整理出 LeetCode 提交专用的极简核心代码,并拆解关键步骤,方便你直接套用、理解。

核心代码

cpp 复制代码
class Solution {
public:
    int maxOperations(vector<int>& nums, int k) {
        // 步骤1:排序(双指针法的前提)
        sort(nums.begin(), nums.end());
        // 步骤2:初始化左右指针 + 计数变量
        int left = 0, right = nums.size() - 1, count = 0;
        // 步骤3:双指针相向移动(核心逻辑)
        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == k) { // 找到和为k的数对
                count++;
                left++;
                right--;
            } else if (sum < k) { // 和太小,左指针右移(增大和)
                left++;
            } else { // 和太大,右指针左移(减小和)
                right--;
            }
        }
        return count;
    }
};

双指针法核心逻辑拆解(必记)

这道题的双指针法可以总结为 3 个固定步骤,几乎所有「两数之和类」双指针题都能套这个逻辑:

步骤 操作 目的
1 排序 sort(nums.begin(), nums.end()) 让数组有序,保证指针移动有明确方向(小的数在左,大的在右)
2 初始化指针 left=0(左指针,指向最小数)、right=n-1(右指针,指向最大数) 从两端开始找数对,覆盖所有可能的组合
3 指针移动规则 - 和 = k:计数 + 1,左右指针都向中间移(数对已用,不能重复)- 和 < k:左指针右移(需要更大的数,增大总和)- 和 > k:右指针左移(需要更小的数,减小总和) 逐步缩小范围,找到所有合法数对

为什么要这么写?(帮你理解,不是死记)

  • 排序后,数组是「升序」的,所以:
    • 左指针右移 → 取更大的数 → 总和变大;
    • 右指针左移 → 取更小的数 → 总和变小;
  • 循环条件是 left < right:保证每个数只被用一次(如果 left == right,只剩一个数,无法组成数对);
  • 每次找到和为 k 的数对,必须同时移动两个指针:因为这两个数已经被「移出数组」(题目要求用一次就删),不能再参与后续配对。

同类题通用模板(举一反三)

只要是「找数组中两数之和为定值,且每个数只能用一次」的题,都可以用这个模板,比如:

  • LeetCode 1. 两数之和(返回下标不行,但返回数对数量 / 是否存在可以);
  • LeetCode 167. 两数之和 II - 输入有序数组(直接省掉排序步骤)。

小技巧(刷题时快速验证)

用这道题的示例 2 手动走一遍流程,就能秒懂:示例 2:nums = [3,1,3,4,3]k=6

  1. 排序后:nums = [1,3,3,3,4]
  2. 初始:left=0(1)right=4(4) → 和 = 5 < 6 → left++(left=1);
  3. left=1(3)right=4(4) → 和 = 7 > 6 → right--(right=3);
  4. left=1(3)right=3(3) → 和 = 6 == 6 → count=1,left++(2),right--(2);
  5. 此时 left=2right=2 → 循环结束,返回 count=1(和答案一致)。
相关推荐
XLYcmy5 小时前
高级密码生成器程序详解:专门设计用于生成基于用户个人信息的密码猜测组合
开发语言·数据结构·python·网络安全·数据安全·源代码·口令安全
AI科技星5 小时前
时空的固有脉动:波动方程 ∇²L = (1/c²) ∂²L/∂t² 的第一性原理推导、诠释与验证
数据结构·人工智能·算法·机器学习·重构
阿豪只会阿巴5 小时前
【多喝热水系列】从零开始的ROS2之旅——Day4
c++·笔记·python·ros2
军军君015 小时前
Three.js基础功能学习五:雾与渲染目标
开发语言·前端·javascript·学习·3d·前端框架·three
charlie1145141915 小时前
FreeRTOS:软件定时器(Software Timers)与时间管理
开发语言·笔记·学习·freertos·实时操作系统·工程
2401_841495645 小时前
【LeetCode刷题】寻找重复数
数据结构·python·算法·leetcode·链表·数组·重复数
laplace01235 小时前
LangChain 1.0 入门实战(Part 1)详细笔记
笔记·python·langchain·numpy·pandas
罗技1235 小时前
Easysearch 集群监控实战(下):线程池、索引、查询、段合并性能指标详解
前端·javascript·算法
一路往蓝-Anbo6 小时前
C语言从句柄到对象 (七) —— 给对象加把锁:RTOS 环境下的并发安全
java·c语言·开发语言·stm32·单片机·嵌入式硬件·算法
中國龍在廣州6 小时前
谈谈2025年人工智能现状及发展趋势分析
人工智能·深度学习·算法·自然语言处理·chatgpt·机器人·机器人学习