求:
给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例 1:
输入:[-4,-1,0,3,10]
输出:[0,1,9,16,100]
示例 2:
输入:[-7,-3,2,3,11]
输出:[4,9,9,49,121]
提示:
1 <= A.length <= 10000
-10000 <= A[i] <= 10000
A 已按非递减顺序排序。
题目链接: https://leetcode-cn.com/problems/squares-of-a-sorted-array/
解:
1、原地排序
原地求各个数的平方数,然后对平方数数组原地排序。
-
时间复杂度:O(Nlog N),其中 N是数组
A
的长度。 -
空间复杂度:O(1)
public int[] sortedSquares(int[] A) { for (int i = 0; i < A.length; i++) A[i] *= A[i]; Arrays.sort(A); return A; }
2、双指针法
因为题目已经交代A是有序的,那么可以认为,原数组中的每个数进行平方操作后,负数的平方是降序排列,而正数的平方是升序排列。因此我们很自然的想到可以使用双指针法进行优化。我们先找到第一个非负数出现的位置,记为j。再令i=j-1,则i指向最后一个负数出现的位置。然后i反向遍历数组,直到i==0,j正向遍历数组,直到j==N-1(数组A的长度),这样i,j对应的A[i],A[j]的平方数就分别是递增排列的,移动i,j指针,将较小者不断拷贝到ret数组,当i,j中有一个遍历完成时,另一个可能还没有完成遍历(负数和非负数数量一般不等),此时我们再遍历所有剩余元素,直接拷贝到ret数组。最终得到的ret数组即为所求。
- 时间复杂度:O(N),其中 N是数组
A
的长度。 - 空间复杂度:O(N)
public int[] sortedSquares(int[] A) { int N = A.length; int ret[] = new int[N]; int i = 0, j = 0, k = 0; while (j < N && A[j] < 0) ++j; i = j - 1; while (i >= 0 && j < N) { if (A[i] * A[i] < A[j] * A[j]) { ret[k++] = A[i] * A[i]; --i; } else { ret[k++] = A[j] * A[j]; ++j; } } while (i >= 0) { ret[k++] = A[i] * A[i]; --i; } while (j < N) { ret[k++] = A[j] * A[j]; ++j; } return ret; }
来源:oschina
链接:https://my.oschina.net/u/4469818/blog/4332686