Easy
题目描述
给你一个按 非递减顺序 排序的整数数组 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]
提示:
1 <= nums.length <= 10^4-10^4 <= nums[i] <= 10^4nums已按 非递减顺序 排序
进阶: 请你设计时间复杂度为 O(n) 的算法解决本问题
解题思路
解题思路
这道题有两种主要解法:
方法一:直接平方后排序
最直观的方法是对每个元素平方,然后排序。时间复杂度为 O(n log n)。
方法二:双指针(推荐)
由于原数组已经有序,我们可以利用这个特性。观察发现,平方后最大的元素一定出现在数组的两端(最小的负数或最大的正数)。
使用双指针技巧:
- 左指针指向数组开头,右指针指向数组末尾
- 比较两端元素的平方值大小
- 将较大的平方值放入结果数组的末尾
- 移动对应指针,继续比较
- 从后向前填充结果数组
这样可以在 O(n) 时间内完成,且只需要 O(1) 额外空间(不考虑结果数组)。
核心思想是利用原数组的有序性,通过双指针从两端向中间收缩,每次选择平方值较大的元素放入结果数组。
代码实现
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector<int> result(n);
int left = 0, right = n - 1;
int pos = n - 1;
while (left <= right) {
int leftSquare = nums[left] * nums[left];
int rightSquare = nums[right] * nums[right];
if (leftSquare > rightSquare) {
result[pos] = leftSquare;
left++;
} else {
result[pos] = rightSquare;
right--;
}
pos--;
}
return result;
}
};
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
result = [0] * n
left, right = 0, n - 1
pos = n - 1
while left <= right:
left_square = nums[left] ** 2
right_square = nums[right] ** 2
if left_square > right_square:
result[pos] = left_square
left += 1
else:
result[pos] = right_square
right -= 1
pos -= 1
return result
public class Solution {
public int[] SortedSquares(int[] nums) {
int n = nums.Length;
int[] result = new int[n];
int left = 0, right = n - 1;
int pos = n - 1;
while (left <= right) {
int leftSquare = nums[left] * nums[left];
int rightSquare = nums[right] * nums[right];
if (leftSquare > rightSquare) {
result[pos] = leftSquare;
left++;
} else {
result[pos] = rightSquare;
right--;
}
pos--;
}
return result;
}
}
var sortedSquares = function(nums) {
const n = nums.length;
const result = new Array(n);
let left = 0, right = n - 1;
let pos = n - 1;
while (left <= right) {
const leftSquare = nums[left] * nums[left];
const rightSquare = nums[right] * nums[right];
if (leftSquare > rightSquare) {
result[pos] = leftSquare;
left++;
} else {
result[pos] = rightSquare;
right--;
}
pos--;
}
return result;
};
复杂度分析
| 复杂度类型 | 双指针解法 | 直接排序解法 |
|---|---|---|
| 时间复杂度 | O(n) | O(n log n) |
| 空间复杂度 | O(1) | O(1) |
注:空间复杂度不包括结果数组的存储空间
相关题目
. Merge Sorted Array (Easy)
. Sort Transformed Array (Medium)