思路
思路一
数组元素全部平方后,再排序
算法时间复杂度是O(logn+n)
思路二
-
定义新数组存放平方比较后的值
-
使用左右指针思想,分别指向首和尾的元素
-
通过移动左右指针比较所有元素
-
移动指针比较大小,较大者的数据存放进新数组,新数组从右往左接收数据
思路二的解析
-
题目要求排序后的数组大小为从小到大,因此数组接收数据有从右往左和从左往右,前者需接受较大值依次接受次大值;后者反之即可
-
本题使用的左右指针(双指针思想),是考虑数组元素存在负数(只存在整数的数组平方后各元素的大小关系没有发生变化),最小的负数平方后可能为最大值,因此我们首先比较最大值,再比较次大值,依次进行,故新数组接受数据是从右往左而不是从左往右。
-
或许有同学对不先比较最小值存在疑惑。因为数组中的负数和整数的分界点在哪,我们不知道,虽然我们可以通过库函数或遍历打印,但是计算机不知道。
-
但是最大值很好比较,因为数组元素是非递减排序(存在相同的元素,不能称作递增排序),最小值和最大值就位于数组的头和尾,头元素平方后是否是最大值,直接与尾元素比较即可得知。
流程
-
定义一个新数组
-
定义一个下标k(新数组),下标变化由大到小
疑惑点
-
for循环中i≤j,而不是i<j。后者会造成剩余一个元素没被处理。
-
i++和j–。是由执行条件的,因此不能直接在for循环的条件里。他们二者是用来比较指向的数值的大小,谁大则谁移动到另一个元素再比较
代码实现
class Solution {
public int[] sortedSquares(int[] nums) {
//定义一个新数组,及其下标
int[] result=new int[nums.length];
int index=nums.length-1;
//循环遍历待处理的数组,双指针思想,left,right,
for(int left=0,right=nums.length-1;left<=right;){
//当左指针指向的值大于右指针指向的值,则前者赋值给新数组,左指针右移
if(nums[left]*nums[left]>nums[right]*nums[right]){
result[index--]=nums[left]*nums[left];
left++;
}
//反之,新数组接收后者,右指针左移
else{
result[index--]=nums[right]*nums[right];
right--;
}
}
return result;
}
}