给你一个按 非递减顺序 排序的整数数组 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]
第一种解法: 这是最直白的一种解法了,就是先乘方再排序
var sortedSquares = function(nums) {
var n = [];//新数组,用来装新的数
var len = nums.length;
for(let i = 0;i<len;i++){
n[i]=Math.pow(nums[i],2);
}
n.sort((a,b)=>a-b);
return n;
};
高效解法: 这种解法用的是双指针,但是其实不是很容易想到。 首先,我们要知道,原数组是按非递减顺序排列的,也就是说,这些数乘方后,按照原顺序排列大小可能是 / 先下后上,所以这时可以运用双指针来比大小,然后依次将数字以一个从大到小的方式排到new array中作为最后的返回值。
而且双指针的解法直接吊打刚才的写法,因为刚才采用的排序的算法是冒泡排序,时间复杂度很高,这种双指针的排序方法基本是常数时间级别的
var sortedSquares = function(nums) {
var len = nums.length;
var n = new Array(len-1);//新数组,用来装新的数
var index = len-1;
var left = 0;
var right = len-1;
while(index>=0){
if(nums[right]+nums[left]>=0){//right指向的数绝对值大
n[index]=nums[right]*nums[right];
right --;
}else if(nums[right]+nums[left]<0){//left指向的数绝对值大
n[index]=nums[left]*nums[left];
left ++;
}
index--;
}
return n;
};