方法1
1.思路:最简单的方法就是将数组平方,然后对新的数组使用快排。但是这没有用到题目中数组已经有序的信息。可以将数组分为两部分,左边为负数,右边为非负数,这样平方后分为两个子数组,左边的递减,右边的递增,然后将两个数组排序插入到新的数组即可。首先找到最后一个负数的位置,没有则为-1.设置双指针left和right,left指向最后一个负数,right指向第一个正数。循环的条件是while(left >= 0 || right < nums.length)。此时包含四种情况:
1)左边的指针指向了-1,这种情况可能是没有负数或者有负数,但是已经全部放置进了新的数组。
2)右边的数组指向了nims.length。同理可能是没有正数,或者正数已经放入完毕。
3)左右指针都在中间,左边的平方和小。
4)左右指针都在中间,右边的平方和大。
2.代码:
class Solution {
public int[] sortedSquares(int[] nums) {
int flag = -1;
for(int i = 0; i < nums.length; i++){
if(nums[i] < 0){
flag = i;
}else {
break;
}
}
int[] arr = new int[nums.length];
int left = flag;
int right = flag + 1;
int index = 0;
while (left >= 0 || right < nums.length){
if(left == -1){
arr[index] = nums[right] * nums[right];
right++;
}else if(right == nums.length){
arr[index] = nums[left] * nums[left];
left--;
}else if(nums[left] * nums[left] < nums[right] * nums[right]){
arr[index] = nums[left] * nums[left];
left--;
}else {
arr[index] = nums[right] * nums[right];
right++;
}
index++;
}
return arr;
}
}
3.复杂度分析:
时间复杂度:0(n).因为只需遍历一遍新数组,将元素放入。
空间复杂度:0(1).只需设置几个变量保存数值。
方法2
1.思路:既然平方之后的数组是左边递减,右边递增,则可以设置左右两个指针分别指向头和尾,只要将大的元素放入新数组即可。这种情况无需多考虑,只需比较两天的平方和大小即可,即使是全正数或者全负数,也是边上大。
2.代码:
class Solution {
public int[] sortedSquares(int[] nums) {
int[] arr = new int[nums.length];
int index = nums.length - 1;
for (int l = 0, r =nums.length - 1; l <= r;){
if(nums[l] * nums[l] > nums[r] * nums[r]){
arr[index] = nums[l] * nums[l];
l++;
}else {
arr[index] = nums[r] * nums[r];
r--;
}
index--;
}
return arr;
}
}
3.复杂度分析:同上