给你一个按 非递减顺序 排序的整数数组 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 已按 非递减顺序 排序
进阶:
请你设计时间复杂度为 O(n) 的算法解决本问题
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/squares-of-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
看到这个问题就想使用 in-place 算法,然后再结合双指针的运用来解决这个问题,但是总是会遇到问题,看了看之前的算法都又开辟了一个新数组然后又借助了一个新的指示变量去在新数组里面进行分配数据。
** In-Place 半成品
vector<int> sortedSquares(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while( left <= right ){
int leftSquire = nums[left] * nums[left];
int rightSquire = nums[right] * nums[right];
if( leftSquire > rightSquire ){
int tmp = nums[right];
nums[right] = leftSquire;
nums[left] = tmp;
}else{
nums[right] = rightSquire;
}
right--;
}
return nums;
}
我感觉我还能再试一试
分析一下 in-place 方式为写不出来这个排序?
对于直接在原数据进行修改的话会打乱原数据的顺序,有点像归并排序,都是建立在原数据是有序的前提之下的。进而in-place 方式不可行。
非In-place 解法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int left = 0, right = nums.size()-1, index = nums.size()-1;
vector<int> res(nums.size(), 0);
while(left <= right){
if( getAbs(nums[left]) > getAbs(nums[right])){
res[index--] = nums[left] * nums[left];
left++;
}else{
res[index--] = nums[right] * nums[right];
right--;
}
}
return res;
}
int getAbs(int x){
return x < 0 ? -x : x;
}
};
总结一波,
这个问题的解决思路是通过比较两端的值来确定最终结果数组的中最大值的,因为结果数组中的值是原数组元素的平方,并且负数越小平方值越大,所以最大值一定会在原数组的两端中出现。因此利用双指针的算法就是通过两端的指针不断的向中心靠拢,从而得到一个有序的平方数组。又因为题目要求的是以非递减的顺序进行排序,所以最终的结果数组是从末尾开始填充结果数组元素。