977.有序数组的平方
力扣题目链接:977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 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 <= 104-104 <= nums[i] <= 104nums已按 非递减顺序 排序
进阶:
- 请你设计时间复杂度为
O(n)的算法解决本问题
1、暴力法
思路
将数组 nums 中的数平方后直接排序。
代码
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for (int i = 0; i < nums.size(); ++i) {
nums[i] *= nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
复杂度分析
- 时间复杂度:O(nlogn)
- 空间复杂度:O(1)
2、双指针法
思路
题目中的数组是按照升序排序的,那么数组平方的最大值就在数组的两端,我们可以使用两个指针分别指向数组的起始位置和终止位置。每次比较两个指针对应的数,选择较大的那个逆序放入数组并移动指针。
代码
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
// 定义两个指针i和j,分别指向输入数组的起始和末尾位置
int i = 0;
int j = n - 1;
// 定义变量k,用于记录新数组的最后一个元素的下标
int k = n - 1;
// 创建result数组,并将所有元素初始化为0
vector<int> result(n, 0);
// 注意这里要i <= j,当i和j相遇时,还需要处理最后一个元素
while (i <= j) {
int left_square = nums[i] * nums[i];
int right_square = nums[j] * nums[j];
// 如果左边的平方小于右边的平方
if (left_square < right_square) {
// 将右边的平方放入结果数组的第k个位置,并将k减1
result[k--] = right_square;
// 将指针j向前移动一位
--j;
// 否则
} else {
// 将左边的平方放入结果数组的第k个位置,并将k减1
result[k--] = left_square;
// 将指针i向后移动一位
++i;
}
}
return result;
}
};
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)