版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17677907/article/details/88086618
977 有序数组平方排序题解
方法一 排序
思路与算法
创建一个新的数组,它每个位置是给定数组对应位置元素的平方,然后对这个数组进行排序。
python
def sortedSquares(A):
return sorted(x*x for x in A)
c++
vector<int> sortedSquares(vector<int>& A) {
for(int i=0;i<A.size();i++)
{
A[i]=A[i]*A[i];
}
sort(A.begin(),A.end());
return A;
}
复杂度分析
- 时间复杂度 O(N*logN) N是数组的长度
- 空间复杂度 O(N)
注意
这里需要注意的是sort和sorted方法的区别
Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列。
sorted(iterable,key=None,reverse=False),返回新的列表,对所有可迭代的对象均有效
sort(key=None,reverse=False) 就地改变列表 reverse:True反序;False 正序
区别如下:
- sort只能对list排序 sorted可以对所有的可迭代序列排序
- sort就地改变列表,没有返回值 sorted返回新的列表
方法二 双指针
思路
因为数组 A 已经排好序了, 所以可以说数组中的负数已经按照平方值降序排好了,数组中的非负数已经按照平方值升序排好了。
举一个例子,若给定数组为 [-3, -2, -1, 4, 5, 6],数组中负数部分 [-3, -2, -1] 的平方为 [9, 4, 1],数组中非负部分 [4, 5, 6] 的平方为 [16, 25, 36]。我们的策略就是从前向后遍历数组中的非负数部分,并且反向遍历数组中的负数部分。
算法
我们可以使用两个指针分别读取数组的非负部分与负数部分 —— 指针 i 反向读取负数部分,指针 j 正向读取非负数部分。
那么,现在我们就在使用两个指针分别读取两个递增的数组了(按元素的平方排序)。接下来,我们可以使用双指针的技巧合并这两个数组。
python
def sortedSquares(A):
N = len(A)
# i, j: negative, positive parts
j = 0
# 找到非负数的位置
while j < N and A[j] < 0:
j += 1
i = j - 1
ans = []
while 0 <= i and j < N:
if A[i]**2 < A[j]**2:
ans.append(A[i]**2)
i -= 1
else:
ans.append(A[j]**2)
j += 1
# 对可能有剩余的情况进行处理
while i >= 0:
ans.append(A[i]**2)
i -= 1
while j < N:
ans.append(A[j]**2)
j += 1
return ans
C++
vector<int> sortedSquares(vector<int>& A) {
int zheng=0;
int N = A.size();
vector<int> res;
while (zheng < N && A[zheng] < 0)
zheng++;
int fu=zheng-1;
while(zheng<N && fu>=0)
{
if(A[fu]*A[fu]<=A[zheng]*A[zheng]){
res.push_back(A[fu]*A[fu]);
fu--;
}
else{
res.push_back(A[zheng]*A[zheng]);
zheng++;
}
}
while(zheng<N){
res.push_back(A[zheng]*A[zheng]);
zheng++;
}
while(fu>=0){
res.push_back(A[fu]*A[fu]);
fu--;
}
return res;
}
复杂度分析
- 时间复杂度 O(N) N是数组的长度
- 空间复杂度 O(N)