Q
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
A
暴力
1 |
|
时间复杂度
O(nlogn),其中 n 是数组 A 的长度。空间复杂度
O(logn)。除了存储答案的数组以外,需要 O(logn) 的栈空间进行排序。
双指针(中位向两边)
1 |
|
- 思路
显然,如果数组 A 中的所有数都是非负数,那么将每个数平方后,数组仍然保持升序;如果数组 A 中的所有数都是负数,那么将每个数平方后,数组会保持降序。
这样一来,如果我们能够找到数组 A 中负数与非负数的分界线,那么就可以用类似「归并排序」的方法了。具体地,我们设 neg 为数组 A 中负数与非负数的分界线,也就是说,A[0] 到 A[neg] 均为负数,而 A[neg+1] 到 A[n−1] 均为非负数。当我们将数组 A 中的数平方后,那么 A[0] 到 A[neg] 单调递减,A[neg+1] 到 A[n−1] 单调递增。
由于我们得到了两个已经有序的子数组,因此就可以使用归并的方法进行排序了。具体地,使用两个指针分别指向位置 neg 和 neg+1,每次比较两个指针对应的数,选择较小的那个放入答案并移动指针。当某一指针移至边界时,将另一指针还未遍历到的数依次放入答案。
时间复杂度
O(n),其中 n 是数组 A 的长度空间复杂度
O(1)
双指针(两边至中间)
1 |
|
思路
同样地,可以使用两个指针分别指向位置 0 和 n−1,每次比较两个指针对应的数,选择较大的那个逆序放入答案并移动指针。这种方法无需处理某一指针移动至边界的情况,时间复杂度
O(n),其中 n 是数组 A 的长度空间复杂度
O(1)