有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
解法一:直接排序
思想很简单,求完平方之后直接进行排序即可。
代码如下:
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
for i in range(len(nums)):
nums[i] = nums[i]*nums[i]
return sorted(nums)
解法二:归并排序
在对数组元素依次进行平方后,我们会发现0之前的元素是递减的,0之后的元素则是递增的,那么我们就在一个数组中有了两段有序的序列。
这样一来,我们就可以直接对这两段有序序列进行归并排序。
代码如下:
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
negative = -1
for i, num in enumerate(nums):
if num < 0:
negative = i
else:
break
ans = list()
i, j = negative, negative + 1
while i >= 0 or j < n:
if i < 0:
ans.append(nums[j] * nums[j])
j += 1
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
这种方法之所以称为双指针是因为有两个有序序列,所以我们在对两个序列进行合并时,需要两个指针来指向对应元素,即上述代码中的i
和j
,故称为双指针。
上面这段代码,指针i
和j
分别指向了0的两边的元素,即负数的最大值和正数的最小值,所以插入到结果ans
是正序插入。
另外一种方法可以使i
和j
分别指向数组的第0个元素和第n-1个元素,这样的话每次插入结果ans
时为逆序插入。和上面思想是一样的只是指针位置、插入位置改变了一下。
代码如下:
class 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