题目
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
cpp
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
cpp
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
提示:
- 1 <= nums.length <= 104
- 104 <= nums[i] <= 104
- nums 已按 非递减顺序 排序
思路
方法一: 先求解,再排序。
cpp
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
for (int i = 0; i < A.size(); i++) {
A[i] *= A[i];
}
sort(A.begin(), A.end()); // 快速排序
return A;
}
}
方法2 :牺牲空间来换取时间复杂度:
思路:既然起始时顺序是排好的,只不过第一个位置的负的元素可能平方后可能是最大的,也有可能是最后一个元素的平方后是最大的,要排在最后。既然这样,最大的数排在最后或者开头(负数),因此不会在中间。
1、定义一个新的数组result
用来结果,定义一个变量k
指向result最后一个位置,当有最大的数据筛选出来时,每次把它移入到新数组组中。
2、定义两个"指针"i
,j
分别指向原数组nums的数组的起始位置和末尾位置。
3、如果num[i]*nums[i]>nums[j]*nums[j]
时,说明起始位置的元素比较大。将其移入到新元素的末位置中,同时使得k--
,i++
。
4、如果num[i]*nums[i]<=nums[j]*nums[j]
时,说明起始位置的元素比较小,末尾元素比较大。将其移入到新元素的末位置中,同时使得k--
,j--
;
5、最后返回result数组即可。
代码实现:
cpp
//方法2 @i want to 武动乾坤 2023/08/08
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k=nums.size()-1;//使得k指向result数组最后一个位置
vector<int> result(nums.size(),0);//定义result容器
for(int i=0,j=nums.size()-1;i<=j;){//i<=j保证最后两个数据也能被比较加入新数组
if(nums[i]*nums[i]>nums[j]*nums[j]){//起始位置大
result[k--]=nums[i]*nums[i];//注意k--是先赋值再--
//等同于result[k]=nums[i]; k--;
i++;//指针向后移动
}else{
result[k--]=nums[j]*nums[j];//注意k--是先赋值再--
//等同于result[k]=nums[i]*nums[i]; k--;
j--;//指针向前移动
}
}
return result;//返回新的结果集
}
};