【LeetCode】977. 有序数组的平方

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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值