LeetCode 977 有序数组的平方

Leetcode 977 有序数组的平方

题目描述:

给你一个按 非递减顺序 排序的整数数组 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:
#直接排序
class Solution:

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

这是最简单,代码量最少的一种解法,直接将nums中的数平方后直接排序。但是没有用到这一条件:给定的数组是按照非递减顺序。

解法2:
#双指针

lass Solution:

  def sortedSquares(self, nums: List[int]) -> List[int]:

​    n=len(nums)

​    ans=[0]*n

​    i,j,pos=0,n-1,n-1while i<=j:if nums[i]*nums[i]>nums[j]*nums[j]:

​        ans[pos]=nums[i]*nums[i]

​        i+=1else:

​        ans[pos]=nums[j]*nums[j]

​        j-=1

​      pos-=1return ans

可以使用双指针分别指向0,n-1,每次比较两个指针对应的数,选择较大的那个逆序(或者选择较小的那个顺序也行)放入答案并移动指针,同时,这种方法也无需处理某一指针移动至边界的情况。

解法3(超时?):
#双指针、归并排序
class Solution:

  def sortedSquares(self, nums: List[int]) -> List[int]:

​    n = len(nums)

​    negative = -1#python的变量不用声明,i,num用于记录python内置函数#enumerate的返回,即列表nums的下标和下标对应的数值for i, num in enumerate(nums):if num<0:

​        negative=i

​      else:break

​    ans=list()#nums[0]到nums[i]均为负数#nums[j]到nums[n-1]均为正数

​    i,j=negative,negative+1#当指针移至边界时,将另一指针还未遍历到的数依次放入答案while i>=0 or j<n:if i<0:

​        ans.append(nums[j]*nums[j])elif j==n:

​        ans.append(nums[i]*nums[i])

​        i-=1#归并排序elif nums[i]*nums[i]<nums[j]*nums[j]:

​        ans.append(nums[i]*nums[i])

​        i-=1else:

​        ans.append(nums[j]*nums[j])

​        j+=1return ans

解法1没有利用(数组nums已经按照升序排序)这个条件,显然,如果数组nums中的所有数都是非负数,那么将每个数平方之后,数组仍然保持升序;如果数组nums中的所有数都是负数,那么将每个数平方之后,数组仍然保持降序。

这样一来,如果我们能够找到数组nums中负数与非负数的分界线,那么就可以用类似归并排序的方法,具体的,我们可以设置一个变量negative,作为负数与非负数的分界线,也就是说,nums[0]到nums[negative]均为负数,nums[negative+1]到num[n-1]均为非负数。当我们对数组中的数进行平方操作后,那么nums[0]到nums[negative]单调递减,nums[negative+1]到nums[n-1]单调递增。

由于我们已经得到了两个已经有序的子数组,因此就可以使用归并的方法进行排序。具体地,使用两个指针分别指向negative和negative+1,每次比较两个指针对用的数,选择较小的那个放入答案并移动指针,当某一指针移至边界时,将另一指针还未遍历到的数依次放入答案。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周泡泡同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值