在题目中给出一个按非递减顺序排列的数组,要求返回一个也是非递减顺序的数字平方的数组。
所以我的第一反应就是先平方再排序,平方后的数组一共有以下三种情况:
1.递减
eg:原数组[-4, -3, -2, -1, 0]
平方后:[16, 9, 4, 1, 0]
2.递增
eg:原数组[0, 1, 2, 3, 4]
平方后:[0, 1, 4, 9, 16]
3.先递减再递增
eg:原数组[-4, -1, 0, 3, 10]
平方后:[16, 1, 0, 9, 100]
注意平方后的所有情况,我们可以发现最大值在数组的最左或最右;在去掉最大值后,次大值也是在数组的最左或最右;去掉次大值后,次次大值也是在数组的最左或最右……
得到这个规律后我们可以使用双指针(当作比较区间!),一个指针在数组最左端,另一个在数组最右边。将指针位置上的数值比较,大的一方放在新数组的最右端并更新这个指针的指向(+1或-1)。当左边的指针位置大于右边的指针位置时说明比较完成。
代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int[] new_nums = new int[nums.length];
//写入的顺序是从大到小
int write = nums.length - 1;
//平方
for(int i =0; i <nums.length; i++){
nums[i] = nums[i] * nums[i];
}
// 左指针大于右指针位置后不再比较
while (left <= right){
//左指针位置上的数大 将该数放在新数组中没更新过的最右位置(即从大到小写入)
if (nums[left] > nums[right]){
new_nums[write] = nums[left];
// 左指针右移
left ++;
// 更新 新数组待写入的位置
write --;
}
else {
//右指针上的数大
new_nums[write] = nums[right];
right --;
write --;
}
}
return new_nums;
}
}