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/4 22:51:49

Callback实战案例:早停、学习率调度与日志记录

Callback实战案例&#xff1a;早停、学习率调度与日志记录 在大模型训练的世界里&#xff0c;一个微小的配置失误可能意味着几十小时GPU算力的浪费&#xff1b;一次未被察觉的过拟合&#xff0c;可能导致整个微调任务前功尽弃。随着模型参数规模突破百亿甚至千亿&#xff0c;传…

作者头像 李华
网站建设 2026/6/5 0:02:39

java计算机毕业设计学科竞赛管理系统 高校毕业设计:基于SpringBoot的大学生竞赛报名与评审一体化平台 本科项目实战:Web端学科竞赛全流程跟踪与成绩管理系统

计算机毕业设计学科竞赛管理系统b7wj69 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。“互联网”大赛、数学建模、RoboMaster……当竞赛成为保研加分硬通货&#xff0c;QQ群、E…

作者头像 李华
网站建设 2026/6/8 19:51:10

java计算机毕业设计虚拟物品交易系统 高校毕业设计:基于SpringBoot的虚拟商品商城与订单管理系统 本科项目实战:Web端数字藏品寄售与竞拍平台

计算机毕业设计虚拟物品交易系统qpolf9&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。游戏皮肤、会员兑换码、数字藏品……当“看得见却摸不到”的商品也能秒成交&#xff0c;毕…

作者头像 李华
网站建设 2026/6/4 19:43:20

你还在低效调用Python?C语言集成Python热点函数的3种高阶手法

第一章&#xff1a;C 语言 Python 热点函数调用 在高性能计算和系统级编程中&#xff0c;Python 因其简洁语法被广泛用于原型开发&#xff0c;但执行效率受限于解释器开销。对于计算密集型任务&#xff0c;将热点函数用 C 语言实现&#xff0c;并通过接口与 Python 集成&#x…

作者头像 李华
网站建设 2026/6/9 19:44:30

支持100+评测集:覆盖语言理解、数学、代码等维度

支持100评测集&#xff1a;覆盖语言理解、数学、代码等维度 在大模型技术飞速演进的今天&#xff0c;一个现实问题正困扰着越来越多的开发者&#xff1a;我们如何客观地判断一个模型到底“强”在哪里&#xff1f;又“弱”在何处&#xff1f; 过去&#xff0c;评估一个模型可能只…

作者头像 李华