题目:
给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例 1:
输入:[-4,-1,0,3,10]
输出:[0,1,9,16,100]
来源:力扣(LeetCode)
解:
这道题如果直接求解再直接原数组排序,倒是节省空间,但是再快也要O(nlogn),所以这里不采用。
一个有序数组如果全负或全正,那么我们就可以获得平方后的有序数组。所以我们把数组看成两部分,前半部分为负数组,后半部分为正数组(含0),采用双指针方法从边界(正负端都是从大到小)遍历平方,然后比较大小插入辅助数组,就可获得一个“正负双数组”拼接而成的平方数组。
class Solution {
public int[] sortedSquares(int[] A) {
int[] rs=new int[A.length];
int s=0,e=A.length-1,id=A.length-1;
while(s<=e){
if((A[s]*A[s])>=(A[e]*A[e])){
rs[id--]=A[s]*A[s++];
}else{
rs[id--]=A[e]*A[e--];
}
}
return rs;
}
}
这里顺便提一下,不要总是习惯去调用Java工具类,我在算平方时调用了java.lang.Math.pow(a,b),结果时间上为3ms,如果直接计算时间为1ms,所以简单运算时自己写一下就好,调函数时可能会增加系统不必要的开销。
出于好奇,如果是提前算平方(多遍历一次),节省计算量,时间会是多少?结果还是1ms,LeetCode只支持到ms层,所以要快很多才能到达0ms。当然有兴趣可以自己提高数据量测速。
class Solution {
public int[] sortedSquares(int[] A) {
int[] rs=new int[A.length];
for(int i=0;i<A.length;i++){
A[i]*=A[i];
}
int s=0,e=A.length-1,id=A.length-1;
while(s<=e){
if(A[s]>=A[e]){
rs[id--]=A[s++];
}else{
rs[id--]=A[e--];
}
}
return rs;
}
}