news 2026/5/1 4:11:10

双指针专题(二):两头堵的智慧——「有序数组的平方」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双指针专题(二):两头堵的智慧——「有序数组的平方」

哈喽各位,我是前端小L。

场景想象:

给你一个已经排好序的数组 [-4, -1, 0, 3, 10]。

我们要把每个数平方,然后组成一个新的有序数组。

  • 直觉做法:先把每个数平方[16, 1, 0, 9, 100],然后调用sort()排序。

  • 问题sort()的复杂度是 $O(N \log N)$。面试官通常会问:“能不能用 $O(N)$ 解决?”

思考:

数组其实已经“部分”有序了。

  • 负数部分:越往左,绝对值越大,平方后越大。

  • 正数部分:越往右,绝对值越大,平方后越大。

    也就是说,最大的平方数,一定是在数组的最左边或者最右边! 不可能在中间。

力扣 977. 有序数组的平方

https://leetcode.cn/problems/squares-of-a-sorted-array/

题目分析:

  • 输入:按非递减顺序排序的数组nums(包含负数)。

  • 输出:每个数字的平方组成的新数组,也要按非递减顺序排序。

例子:[-4, -1, 0, 3, 10]

  • 左边-4平方是16

  • 右边10平方是100

  • 100 > 16,所以100肯定是新数组里的老大(最后一名)。

核心思维:左右夹逼 + 逆序填充

既然最大的数一定在两头,那我们就派出两个指针:

  1. 左指针 (left):指向开头(处理负数)。

  2. 右指针 (right):指向结尾(处理正数)。

  3. 结果指针 (k):指向新数组的最后一个位置(因为我们要先找最大的,填到最后去)。

操作逻辑:

  1. 比较nums[left]的平方和nums[right]的平方。

  2. 谁大选谁

    • 如果左边大:把左边的平方填入结果数组的k位置,left移。

    • 如果右边大:把右边的平方填入结果数组的k位置,right移。

  3. k指针向前移动一格,准备填倒数第二大的数。

  4. left > right时,结束。

代码实现 (JavaScript)

JavaScript

/** * @param {number[]} nums * @return {number[]} */ var sortedSquares = function(nums) { let n = nums.length; // 创建一个等长的新数组,用来存放结果 let result = new Array(n); let left = 0; let right = n - 1; // k 指向结果数组的最后一个位置(倒着填) let k = n - 1; // 注意:这里是 left <= right // 因为最后当 left === right 时,剩下的那个元素也要处理(平方后填入) while (left <= right) { let leftSquare = nums[left] * nums[left]; let rightSquare = nums[right] * nums[right]; if (leftSquare > rightSquare) { // 左边的平方更大,填入末尾 result[k] = leftSquare; left++; // 左指针向内收缩 } else { // 右边的平方更大(或相等),填入末尾 result[k] = rightSquare; right--; // 右指针向内收缩 } // 填完一个,k 往前挪一位 k--; } return result; };

深度模拟

输入:[-4, -1, 0, 3, 10]

  1. 初始L=0(-4),R=4(10),k=4

    • 比较:(-4)²=16vs10²=100

    • 选右边。res[4] = 100R变成 3。k变成 3。

    • 状态:[-4, -1, 0, 3],res=[?, ?, ?, ?, 100]

  2. 第二轮L=0(-4),R=3(3)。

    • 比较:16vs9

    • 选左边。res[3] = 16L变成 1。k变成 2。

    • 状态:[-1, 0, 3],res=[?, ?, ?, 16, 100]

  3. 第三轮L=1(-1),R=3(3)。

    • 比较:1vs9

    • 选右边。res[2] = 9R变成 2。k变成 1。

  4. ...以此类推,直到填满。

总结

这道题展示了双指针处理有序数组的强大能力。

  • 只要看到“有序数组”或者“数组部分有序”,且要求找“最大/最小/目标和”,第一反应就应该是左右指针

  • 关键技巧:“从两头往中间找,从后往前填结果”


下一题预告:三数之和

接下来我们要进入双指针专题的深水区了—— LC 15. 三数之和 (Medium)。

这是大厂面试中出现频率最高的算法题之一(绝对的 Top 5)。

  • 题目:给你一个数组,判断是否存在三个数a, b, c使得a + b + c = 0?找出所有不重复的三元组。

  • 难点:

    1. 怎么把三数之和降维?(还是用双指针)。

    2. 怎么去重?(比如数组里有三个-1,怎么保证不输出重复的结果?这是最容易写出 Bug 的地方)。

准备好迎接这道必考题了吗?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 9:42:13

RK3588平台下aarch64与设备树交互机制深度解析

RK3588平台下aarch64与设备树交互机制深度解析从一个启动问题说起&#xff1a;为什么我的外设没被识别&#xff1f;在调试一块全新的RK3588开发板时&#xff0c;你是否遇到过这样的场景&#xff1a;内核顺利启动&#xff0c;串口输出正常&#xff0c;但某个关键外设——比如SPI…

作者头像 李华
网站建设 2026/4/29 7:32:42

AQLM极低比特量化:适用于边缘设备的部署方案

AQLM极低比特量化&#xff1a;适用于边缘设备的部署方案 在消费级笔记本上运行70亿参数的大模型&#xff0c;听起来像是天方夜谭&#xff1f;但在今天&#xff0c;这已经不是幻想。随着AQLM&#xff08;Adaptive Quantization for Large Models&#xff09;等极低比特量化技术的…

作者头像 李华
网站建设 2026/4/29 9:42:22

GPTQ训练支持:逐层量化与误差补偿机制解析

GPTQ训练支持&#xff1a;逐层量化与误差补偿机制解析 在大模型落地日益迫切的今天&#xff0c;一个70亿参数的语言模型动辄需要数十GB显存才能运行&#xff0c;这让许多开发者望而却步。即便拥有A100这样的高端卡&#xff0c;部署多个服务实例依然捉襟见肘。有没有可能让Qwen-…

作者头像 李华
网站建设 2026/4/18 6:48:15

java计算机毕业设计徐福记智能物流园区管理系统 高校毕业设计:基于SpringBoot的智慧仓储物流综合管控平台 本科项目实战:JavaWeb 智能物流园区作业调度与可视化系统

计算机毕业设计徐福记智能物流园区管理系统7j57l9&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。零食巨头徐福记每天上千辆货车进出园区&#xff0c;人工登记、手工派单、纸质出…

作者头像 李华
网站建设 2026/4/28 11:30:15

支持100+评测数据集:学术研究与工业落地双重保障

支持100评测数据集&#xff1a;学术研究与工业落地双重保障 在大模型技术飞速演进的今天&#xff0c;一个现实问题日益凸显&#xff1a;尽管LLaMA、Qwen等主流模型在自然语言理解、视觉推理等领域展现出惊人能力&#xff0c;但真正将其从实验室推向生产环境时&#xff0c;开发…

作者头像 李华
网站建设 2026/5/1 5:48:58

OpenMP 5.3任务模型升级详解:从入门到精通的8个关键知识点

第一章&#xff1a;OpenMP 5.3任务模型核心演进OpenMP 5.3 在任务并行模型方面引入了多项关键改进&#xff0c;显著增强了任务调度的灵活性与性能控制能力。这些演进主要集中在任务依赖表达的增强、任务取消机制的标准化以及任务组语义的细化&#xff0c;为复杂并行应用提供了更…

作者头像 李华