题目描述
思路解析动画文字版
记住这条「平方最大值必在两端 → 双指针比两端、大的从结果末尾往前放」,下面每帧都在套它。
比较两端:左端 nums[0]=-7 平方得 49,右端 nums[10]=11 平方得 121。右边平方更大,它该放进当前结果末尾的空位。
把较大的 121(来自 nums[10]=11)填入结果末尾的空位(绿色标记已消费的下标 10)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[0]=-7 平方得 49,右端 nums[9]=9 平方得 81。右边平方更大,它该放进当前结果末尾的空位。
把较大的 81(来自 nums[9]=9)填入结果末尾的空位(绿色标记已消费的下标 9)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[0]=-7 平方得 49,右端 nums[8]=8 平方得 64。右边平方更大,它该放进当前结果末尾的空位。
把较大的 64(来自 nums[8]=8)填入结果末尾的空位(绿色标记已消费的下标 8)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[0]=-7 平方得 49,右端 nums[7]=6 平方得 36。左边平方更大(或相等),它该放进当前结果末尾的空位。
把较大的 49(来自 nums[0]=-7)填入结果末尾的空位(绿色标记已消费的下标 0)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[1]=-5 平方得 25,右端 nums[7]=6 平方得 36。右边平方更大,它该放进当前结果末尾的空位。
把较大的 36(来自 nums[7]=6)填入结果末尾的空位(绿色标记已消费的下标 7)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[1]=-5 平方得 25,右端 nums[6]=4 平方得 16。左边平方更大(或相等),它该放进当前结果末尾的空位。
把较大的 25(来自 nums[1]=-5)填入结果末尾的空位(绿色标记已消费的下标 1)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[2]=-3 平方得 9,右端 nums[6]=4 平方得 16。右边平方更大,它该放进当前结果末尾的空位。
把较大的 16(来自 nums[6]=4)填入结果末尾的空位(绿色标记已消费的下标 6)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[2]=-3 平方得 9,右端 nums[5]=2 平方得 4。左边平方更大(或相等),它该放进当前结果末尾的空位。
把较大的 9(来自 nums[2]=-3)填入结果末尾的空位(绿色标记已消费的下标 2)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[3]=-1 平方得 1,右端 nums[5]=2 平方得 4。右边平方更大,它该放进当前结果末尾的空位。
把较大的 4(来自 nums[5]=2)填入结果末尾的空位(绿色标记已消费的下标 5)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[3]=-1 平方得 1,右端 nums[4]=0 平方得 0。左边平方更大(或相等),它该放进当前结果末尾的空位。
把较大的 1(来自 nums[3]=-1)填入结果末尾的空位(绿色标记已消费的下标 3)。下一帧这个指针就向内移一格,继续比较剩下的区间。
比较两端:左端 nums[4]=0 平方得 0,右端 nums[4]=0 平方得 0。左边平方更大(或相等),它该放进当前结果末尾的空位。
把较大的 0(来自 nums[4]=0)填入结果末尾的空位(绿色标记已消费的下标 4)。下一帧这个指针就向内移一格,继续比较剩下的区间。
一趟扫完,结果数组从后往前被填满,正好是升序:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 121]。左右指针各只走一遍,O(n),比「先平方再排序」的 O(n log n) 更快。
边界先想清:全负数时平方后顺序整个反转,最左的反而最大。
两个高频追问,区分 O(n) 双指针与 O(n log n) 朴素解。
参考代码
def sortedSquares(nums): n = len(nums) res = [0] * n l, r, w = 0, n - 1, n - 1 # w 从末尾往前填 while l <= r: ls, rs = nums[l] ** 2, nums[r] ** 2 if ls >= rs: # 左端平方更大 res[w] = ls; l += 1 else: # 右端平方更大 res[w] = rs; r -= 1 w -= 1 return res复杂度
- 时间:O(n),l、r 各走一遍,合计线性
- 空间:O(n),结果数组;不计返回值则 O(1)
易错点
面试追问把动画讲成自己的话
追问如果不许用双指针,最简单的写法是什么?复杂度?
追问为什么结果要从后往前填,而不是从前往后?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
盛最多水的容器
LeetCode 11 · 中等 · 沿着 对撞双指针套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题