[LeetCode]day4 977.有序数组的平方
977. 有序数组的平方 - 力扣(LeetCode)
一.题目
给你一个按 非递减顺序 排序的整数数组 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]
二.题解
解法一:傻瓜式直接排序
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;
}
};
思路非常简单 就是把数组内每个元素平方之后 调用库函数直接进行排序
时间复杂度比较高,为nlogn
解法二:双指针更复杂解法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> ans;
int q = -1; // 初始q指向ans数组的“尾”
for (int i = 0; i < nums.size(); i++) {
ans.push_back(nums[i] * nums[i]); // 将平方值加入ans
q++; // 增加“尾指针”
// 如果新添加的元素小于之前的元素,说明需要重新插入排序
int temp = ans[q]; // 保存当前插入的平方值
int p = q - 1; // 用p寻找插入位置
// 向前遍历查找插入位置
while (p >= 0 && ans[p] > temp) {
ans[p + 1] = ans[p]; // 右移元素
p--;
}
// 插入当前的平方值
ans[p + 1] = temp;
}
return ans;
}
};
时间复杂度为O(N^2)
这个的思路是将数组从头到尾遍历一遍 每遍历一个元素就加入结果数组中去,将新加入的元素与原来元素的最后一个元素进行对比,如果比它小,则需要重新排序;
解法三:双指针两面夹击法
我们注意观察数组的特征,会存在负数! 类似-5,-3,1,2,3 从数组的两端向内延伸,数的绝对值逐渐减小 所以两端的数据绝对值是最大的。用两个指针从数组的一头一尾向中间进行遍历,每次去比较两端数据谁的平方更大,将更大的逆序放入结果数组中
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int>ans(nums.size()); //注意给数组预留空间
int k= nums.size()-1;
for(int i=0,j=nums.size()-1;i<=j;){
if(nums[i]*nums[i]>nums[j]*nums[j]){
ans[k--]=nums[i]*nums[i];
i++;
}else{
ans[k--]=nums[j]*nums[j];
j--;
}
}
return ans;
}
};
易错点在于需要逆序将数据存放进目标数组中!