力扣LeetCode977:有序数组的平方(python)

LeetCode997:有序数组的平方

题目:

给你一个按非递减顺序 排序的整数数组 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 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序

链接:997.有序数组的平方

双指针法:

  • 数组其实是有序的,只不过负数平方之后可能成为最大的数。
  • 那么数组的平方最大值就在两端,不是左边就是右边,不可能是中间。
  • 此时就可以考虑双指针法了,left在最左侧,right在最右侧,新建一个列表用来存最大的数。

方法一:

双指针法,用绝对值来比较大小(推荐)
此时的时间复杂度为O(n)

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left,right=0,len(nums)-1
        res=[]
        while left<=right:
          if abs(nums[left])<abs(nums[right]): #绝对值比较
            res.append(nums[right]**2)
            right-=1
          else:
            res.append(nums[left]**2)
            left+=1
        res.reverse()
        return res

方法二:

双指针法(推荐)

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        l, r, i = 0, len(nums)-1, len(nums)-1
        res = [float('inf')] * len(nums) # 需要提前定义列表,存放结果
        while l <= r:
            if nums[l] ** 2 < nums[r] ** 2: # 左右边界进行对比,找出最大值
                res[i] = nums[r] ** 2
                r -= 1 # 右指针往左移动
            else:
                res[i] = nums[l] ** 2
                l += 1 # 左指针往右移动
            i -= 1 # 存放结果的指针需要往前平移一位
        return res

方法三:

暴力解法(不推荐)
这个时间复杂度是 O(n + nlogn), 可以说是O(nlogn)的时间复杂度,但为了和下面双指针法算法时间复杂度有鲜明对比,我记为 O(n + nlog n)。

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        for i in range(len(nums)):
          nums[i]*=nums[i]
        nums.sort()
        return nums

方法四:

暴力解法排序+列表推导

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

总结:

  • 当题目是有序数组且要排序时,可以考虑双指针的方法
  • 还有,力扣的运行速度和打败多少用户数字不用太在意,这个不准确,看看玩就行
  • 有人会问,为何在‘方法二’里面要加上res = [float(‘inf’)] * len(nums),而不是res=[ ] ?

答:因为因为在循环中我们需要通过索引来访问和修改结果数组res的元素,而res = [ ]来创建一个空列表是不行的,如果res是一个空列表,那么在循环中无法直接通过索引来访问和修改res的元素,因为在循环开始之前,res没有任何元素。
因此,我们需要提前定义一个与给定数组长度相同的结果数组res,并将其初始化为正无穷大在循环中通过索引来访问和修改res的元素,最终返回结果数组res作为最终的结果

  • 又有人会问,为什么‘方法一’就可以直接res=[ ]?

答:这是因为我们在循环中不需要直接通过索引来访问和修改结果数组res的元素,而是将平方值逐个添加到结果数组res的末尾最后,我们使用res.reverse()将结果数组res倒序排列,得到最终的升序平方数组.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值