977. 有序数组的平方【双指针】
题目
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
难度:简单
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
已按 非递减顺序 排序
进阶:
- 请你设计时间复杂度为
O(n)
的算法解决本问题
题解
-
在提示中的非递减顺序,意思是nums数组是一个递增数组但是不是等量递增数组,递增但是递增的值不固定。
-
同时,在进阶中,要求我们设计o(n)的算法,那么,就不能对数组的中的负数处理后进行整体数组的排序。但是题目要求最后的结果数组是有序的
-
那么,我们可以 先对数组中的负数进行处理,并在处理过程中找到正负数的转折点
-
利用双指针,从转折点开始往两边处理数据,那么久充分利用了原来数组的有序性而不需要对数组进行整体性的排序
class Solution {
public int[] sortedSquares(int[] nums) {
// 对原数组进行处理
int minIndex = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] < 0) {
nums[i] = -nums[i];
}else {
// 当遇到非负数的时候,就是遇到正负数的转折点
break;
}
// 找转折点
if (nums[i] <= nums[minIndex]) {
minIndex = i;
}
}
int[] res = new int[nums.length];
// 双指针依据转折点进行处理
int l = minIndex, r = l + 1, index = 0;
// 注意循环结束的条件
while (l >= 0 && r < nums.length) {
if (nums[l] > nums[r]) {
res[index++] = nums[r] * nums[r];
r++;
} else {
res[index++] = nums[l] * nums[l];
l--;
}
}
// 对残余的数据进行梳理
while (l >= 0) {
res[index++] = nums[l] * nums[l];
l--;
}
while (r < nums.length) {
res[index++] = nums[r] * nums[r];
r++;
}
return res;
}
}
-
时间复杂度:o(n),对数组进行了两次扫描,与数组的长度n有关
-
空间复杂度:o(n),需要与原来数组同长度的数组装结果集,与数组的长度n有关