LeetCode 977. 有序数组的平方 | Python

977. 有序数组的平方


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/squares-of-a-sorted-array/

题目


给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。

示例 1:

输入:[-4,-1,0,3,10]
输出:[0,1,9,16,100]

示例 2:

输入:[-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

  1. 1 <= A.length <= 10000
  2. -10000 <= A[i] <= 10000
  3. A 已按非递减顺序排序。

解题思路


思路:双指针

先审题,题目给定整数数组(非递减排序),要求返回数组中每个数字的平方组成的新数组,但这里要求新数组最终也按非递减顺序排序。

这里看题目中的提示部分:

  1. -10000 <= A[i] <= 10000

数组元素存在负数,而题目最终的要求是将新数组进行排序。

那么,我们可以想到先对数组中的数字进行平方处理,然后对得到的数组进行排序。这里代码如下:

class Solution:
    def sortedSquares(self, A: List[int]) -> List[int]:
        return sorted([num * num for num in A])

上面的代码就是遍历的同时,对数组中的数字进行平方处理,得到新数组进行排序。

双指针

这里主要说一下双指针的方法如何去实现题目的要求?

数组 A 是按非递减顺序排序的,而且 A 中的元素可能存在负数。当 A 中的元素存在负数时,直接对数组中的元素进行平方处理,我们可以发现,此时数组中数字会是两边大,中间小的情况。就以题目中示例 1 来说明:

[-4, -1, 0, 3, 10]

当对其进行平方处理后,得到:

[16, 1, 0, 9, 100]

这就是两边数字比中间大的情况。因为数组原本是有序的,如果像上面存在负数的情况,那么负数部分平方之后,得到是按非递增顺序排序;非负数部分不变还是按非递减顺序排序。

那么根据这个现象,我们就可以定义双指针,分别指向数组首尾,往中间逼近。比较两边数字平方后的大小,将较大的数字放到结果数组中的末尾,移动指针,往前填充数组。

这里说下具体的做法:

  • 定义指针 left,right 分别指向数组首尾;
  • 定义长度为 n 的结果数组 ans 以及游标 cur,其中 cur 指向结果数组末尾,用以从后往前填充数组;
  • 遍历数组,对双指针指向的数字进行平方,然后比较两者的大小:
    • A[left] * A[left] > A[right] * A[right],那么将 A[left] * A[left] 放到结果数组 cur 指向的位置。
    • 否则将 A[right] * A[right]放到结果数组 cur 指向的位置。
  • 重复上面的步骤,直至指针 left > right。这里需要注意维护更新指针 left,right 及游标 cur。

具体的实现代码如下。

class Solution:
    def sortedSquares(self, A: List[int]) -> List[int]:
        n = len(A)
        # 定义指针 left,right
        left = 0
        right = n-1
        # 定义长度为 n 的新数组,以及游标 cur,用以从后往前填充新数组
        # n 这里是原数组的长度
        ans = [0] * n
        cur = n - 1

        # 开始遍历
        while left <= right:
            # 比较 A[left] * A[left] 和 A[right] * A[right]
            # 将较大值放到结果数组中,
            if A[left] * A[left] > A[right] * A[right]:
                ans[cur] = A[left] * A[left]
                # 当 left 指向的元素平方后放到结果数组后,向右移动 left
                left += 1
            else:
                ans[cur] = A[right] * A[right]
                # 当 right 指向的元素平方后放到结果数组后,向左移动 right
                right -= 1
            # 数字填充后,cur 往左移动,等待下次填充
            cur -= 1
        
        return ans

欢迎关注


公众号 【书所集录


如有错误,烦请指正,欢迎指点交流。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值