题目:
给你一个按 非递减顺序 排序的整数数组 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] <= 104
nums
已按 非递减顺序 排序
代码:
# 双指针法1
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
int negative = -1;
for (int i = 0; i < n; ++i) {
if (nums[i] < 0) {
negative = i;
} else {
break;
}
}
vector<int> ans(n);
int i = negative, j = negative + 1;
for (int m = 0; m < n; m++){
if (i < 0) {
ans[m] = nums[j] * nums[j];
++j;
}
else if (j == n) {
ans[m] = nums[i] * nums[i];
--i;
}
else if (nums[i] * nums[i] < nums[j] * nums[j]) {
ans[m] = nums[i] * nums[i];
--i;
}
else {
ans[m] = nums[j] * nums[j];
++j;
}
}
return ans;
}
};
# 双指针法2
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n);
int i = 0, j = n - 1;
for (int m = n - 1; m >= 0; m--){
if (nums[i] * nums[i] > nums[j] * nums[j]) {
ans[m] = nums[i] * nums[i];
i++;
}else {
ans[m] = nums[j] * nums[j];
j--;
}
}
return ans;
}
};
关键思路:
- 两种双指针方法的时间复杂度均为O(n)。
- 第二种方法的思路是,因为是非降序数组,当数组中元素有正有负的时候,最左边元素的绝对值和最右边属于较大元素,可以直接使用i=0和j=nums.size()-1两个指针,一个向右一个向左,选出较大的平方元素,定义新的空数组,从右向左依次赋值。
- 相比第二种方法,第一种方法稍微复杂,需要考虑多种情况。先选出最大的负数元素,用negative做标记,初始值-1,(不存在负数)为-1,或者(全都是负数)为nums.size()-1。第一个指针指向negative位置,作为分界位置,第二个指针为negative+1。有负有正时,两个指针反向比较,赋值给ans。
- 推荐第二种方法。双指针算法中可以两头指针也可以一头指针。
- vector<int> ans(n) 定义长度为n的int数值向量。C++。