news 2026/6/9 21:22:16

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

作者头像

张小明

前端开发工程师

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/6/10 11:06:54

自定义Metric添加教程:满足个性化评估指标需求

自定义Metric添加教程&#xff1a;满足个性化评估指标需求 在大模型应用日益深入各行各业的今天&#xff0c;一个越来越明显的事实是&#xff1a;标准评测指标正逐渐“失灵”。当我们在金融场景中部署客服助手、在电商平台上生成商品文案、或是在医疗领域辅助诊断报告撰写时&a…

作者头像 李华
网站建设 2026/6/10 11:05:36

推理加速引擎选型指南:vLLM/SGLang/LmDeploy怎么选?

推理加速引擎选型指南&#xff1a;vLLM/SGLang/LmDeploy怎么选&#xff1f; 在大模型落地浪潮中&#xff0c;推理效率正成为决定产品成败的关键。一个响应迟缓、吞吐受限的模型服务&#xff0c;即便能力再强&#xff0c;也难以支撑真实业务场景。传统基于 PyTorch 的原生推理方…

作者头像 李华
网站建设 2026/6/10 11:04:16

GitLab CI/CD流水线自动构建DDColor最新镜像版本

GitLab CI/CD 流水线自动构建 DDColor 最新镜像版本 在数字遗产保护和家庭影像修复日益受到关注的今天&#xff0c;如何高效、稳定地部署 AI 图像修复能力&#xff0c;成为开发者与内容机构共同面临的挑战。传统方式中&#xff0c;手动配置依赖、逐台部署环境、版本不一致等问题…

作者头像 李华
网站建设 2026/6/10 11:03:39

Multi-Query Attention实战:共享KV头设计

Multi-Query Attention实战&#xff1a;共享KV头设计 在大模型落地的浪潮中&#xff0c;一个看似微小的设计选择&#xff0c;往往能带来颠覆性的性能差异。想象一下&#xff1a;你的对话机器人正在为上千名用户实时生成回复&#xff0c;突然显存耗尽、请求排队延迟飙升——问题…

作者头像 李华
网站建设 2026/6/10 11:33:09

PyCharm远程调试大模型训练任务?集成开发环境配置技巧

PyCharm远程调试大模型训练任务&#xff1f;集成开发环境配置技巧 在今天的AI工程实践中&#xff0c;一个现实问题摆在每位开发者面前&#xff1a;如何高效调试动辄几十GB显存占用、运行数小时甚至数天的大模型训练任务&#xff1f;传统的“写代码→上传服务器→命令行启动→看…

作者头像 李华
网站建设 2026/6/10 13:04:42

批量评测多个模型:自动化脚本编写技巧

批量评测多个模型&#xff1a;自动化脚本编写技巧 在大模型技术飞速发展的今天&#xff0c;开发者和研究人员面对的不再是“有没有可用模型”的问题&#xff0c;而是“如何从数百个候选模型中快速选出最优解”。以Qwen、LLaMA、ChatGLM为代表的开源模型层出不穷&#xff0c;仅H…

作者头像 李华