Leetcode刷题记录(4):977有序数组的平方

刷题网站:Leetcode

难度: 简单

语言: Python

计划:从简单——>到中等——>再到难。

一、977有序数组的平方

1.1 题目描述:

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

  • 示例1
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]排序后,数组变为 [0,1,9,16,100]
  • 示例2
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
1.2 思考分析

这题最开始想到的思路就是先对整个数组内的数字进行平方,然后进行一个排序。可想而知,时间复杂度为 O ( n l o g n ) O(n logn) O(nlogn),肯定不是最佳的思路。

再回到此题,叫双指针,肯定要利用双指针,那什么叫双指针呢?

双指针旨在遍历对象过程中,使用两个相同方向(快慢指针)或相反方向(对撞指针)的指针进行扫描,从而达到解题目的。

  • 1)快慢指针:旨两个指针从同一方向开始遍历数组,分别定义为快指针(fast)和慢指针(slow),以不同策略移动,直到两个指针的值相等为止。
  • 2)对撞指针:顾名思义,旨在有序数组中,指向最左侧索引定义为左指针(left),最右侧定义为右指针(right),从两头向中间进行数组遍历。(适用于有序数组,例如前面我们介绍的数组二分查找搜索插入位置都是使用对撞指针)

总而言之,遇到有序数组时,应该优先想到双指针来解决问题,两个指针遍历会减少空间复杂度和时间复杂度。

详细内容参考:双指针问题

再次回到本题,我们应该考虑初始有序数组也是有顺序的,所以小于零的部分平方后顺序是从大到小,大于零的部分平方后顺序是从小到大。比较适合用对撞指针方法,完整代码如下:

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        sort = [-1]*len(nums)
        num = len(nums)-1
        k,i= num,0
        while i<=num:
            left = nums[i]*nums[i]
            right = nums[num]*nums[num]
            if left < right:
                sort[k] = right
                num-=1
            else:
                sort[k]=left
                i+=1
            k -= 1
        return sort

执行结果显示,击败了77.7%的用户(每次提交击败的用户都不同,可能根据每个人的电脑配置不一样),只要超过大部分用户,说明该算法还算可以。
在这里插入图片描述

1.3 总结

此题关键理解双指针概念,可能自身有了一个大概了解,后面还需加强该算法的训练。为了以便理解,以一个长一点的例子,用对撞指针来解释:

例如,输入数组[-8, -5, -3, -1, 2, 4, 5, 7],通过上面算法后,先平方后得[64, 25, 9, 1, 4, 16, 25, 49]。然后按照最左与最右比较,大的放右边,以此排序

  • 1)第一步,[64, 25, 9, 1, 4, 16, 25, 49]比较后变成了[ 25, 9, 1, 4, 16, 25, 49, 64]。
  • 2)第二步,[25, 9, 1, 4, 16, 25, 49, 64]比较后变成了[ 9, 1, 4, 16, 25, 25, 49, 64]。
  • 3)第三步,[9, 1, 4, 16, 25, 25, 49, 64]比较后变成了[1, 4, 9, 16, 25, 25, 49, 64]。
  • 4)第四步,[1, 4, 9, 16, 25, 25, 49, 64]比较后,最终结果为[1, 4, 9, 16, 25, 25, 49, 64]。

可知时间复杂度仅为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值