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-1

​    while i<=j:

​      if nums[i]*nums[i]>nums[j]*nums[j]:

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

​        i+=1

​      else:

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

​        j-=1

​      pos-=1

​    return 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-=1

​      else:

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

​        j+=1

​    return ans

方法一没有利用(数组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,每次比较两个指针对用的数,选择较小的那个放入答案并移动指针,当某一指针移至边界时,将另一指针还未遍历到的数依次放入答案。

posted @ 2022-03-26 21:52  zhoupaopaoer  阅读(39)  评论(0)    收藏  举报