需求
给你一个按 非递减顺序 排序的整数数组 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]
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序
进阶:
请你设计时间复杂度为 O(n) 的算法解决本问题
版本1
通过对需求的分析, 先写出第一个版本:
public int[] sortedSquares(int[] nums) {
int length = nums.length;
int[] resultArr = new int[length];
int left = 0;
int right = length - 1;
int index = right;
while( left <= right ){
resultArr[index--] = nums[left] * nums[left] > nums[right] * nums[right]
? nums[left] * nums[left++] : nums[right] * nums[right--];
}
return resultArr;
}
版本1使用了双指针技术来解决问题。left 指针指向数组的起始位置,而 right 指针指向数组的末尾。index 变量则用于跟踪结果数组中最后一个元素的索引。
在 while 循环中,代码比较 left 和 right 指针所指向的数的平方值,将较大的平方值放入结果数组的 index 位置,并更新相应的指针。
如果 nums[left] 的平方大于 nums[right] 的平方,则将 nums[left] 的平方放入结果数组,并将 left 指针向右移动一位;否则,将nums[right] 的平方放入结果数组,并将 right 指针向左移动一位。每次放入平方值后,index 都会递减,直到 left 和 right 指针相遇,循环结束。
这种方法的时间复杂度为O(n),因为它只需要遍历一次原数组。
执行结果很丝滑:
版本2
版本1中的代码 :
resultArr[index--] = nums[left] * nums[left] > nums[right] * nums[right]
? nums[left] * nums[left++] : nums[right] * nums[right--];
我们可以看到 nums[left] * nums[left]
这个表达式执行了两次, 其实执行一次就行了, 只不过我们要用变量将其保存起来.
可以修改为如下代码:
public int[] sortedSquares(int[] nums) {
int length = nums.length;
int[] resultArr = new int[length];
int left = 0;
int right = length - 1;
int index = right;
int leftValue;
int rightValue;
while( left <= right ){
leftValue = nums[left] * nums[left];
rightValue = nums[right] * nums[right];
if( leftValue > rightValue ){
resultArr[index--] = leftValue;
left++;
} else{
resultArr[index--] = rightValue;
right--;
}
}
return resultArr;
}
执行结果依然很丝滑. 就是内存加了点.
注意要点
循环结束条件
在该算法下, 我们的循环结束条件定为了 left <= right
, 这是因为, 我们的双指针分别从左边和最右边向中间靠拢, 而且每次只有一个指针在移动, 并不是一起移动的. 当两个指针重合的时候, 也就是数组的所有数据都遍历比较完成了.
为什么index从数组末尾开始
这是因为需求里是要的平方和, 并且是按照非递减的顺序排列, 而给出的原数组中是存在 负数
的.
所以当我们的两个指针分别从数组起始值和结尾位置比较的时候, 可以找到最大值, 但是不一定能找到最小值. 比如 数组: { -4, 1, 3, 6, 9}; 当我们的两个指针开始比较时候, -4 和 9 分别平方后可以找到最大值, 但是不能找到最小值. 因为 1 平方后会比 -4 平方 要小.
结尾
以上 是我对有序数组平方和的一些遐想和延伸, 可能不是最优解, 但是算法的优化嘛 本身就是一个思索的过程, 能在这个思索和迭代的过程中有所收获和乐趣就是在成长了, 欢迎大家一起来交流更多的解答…