题目
给你一个按 非递减顺序 排序的整数数组 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]**2 nums.sort() return nums
- 双向指针法
考虑到是有序数组,所以只有负数的平方可能会打乱排列顺序。
使用两个指针,一个从前向后,一个从后往前,每次比较两个指针所指向的元素平方值,依次从后往前放入新数组中。其实本质是将负数的平方按顺序插入正数的平方值中。class Solution(object): def sortedSquares(self, nums): """ :type nums: List[int] :rtype: List[int] """ # 双向指针法 s = len(nums)-1 i, j, k = 0, s, s result = [0] * (s+1) while i <= j: if nums[i]**2 <= nums[j]**2: result[k] = nums[j]**2 j -= 1 else: result[k] = nums[i]**2 i += 1 k -= 1 return result
- 双指针(归并排序)
方法2中分析可得,平方后的顺序主要是由负数打乱,所以可以将原数组中的正负分开,变成两个有序数组,再进行归并排序。class Solution(object): def sortedSquares(self, nums): """ :type nums: List[int] :rtype: List[int] """ n = len(nums) nagetive = -1 # 先找出正负数分界点 for i, num in enumerate(nums): if num < 0: nagetive = i else: break # 两个子数组进行排序 result = [] i, j = nagetive, nagetive+1 # 两个指针分别指向负数数组的最后一个元素和非负数组的第一个元素 while i >= 0 or j < n: if i < 0: # i<0说明负数平方已经排序完,按顺序将剩下的非负数组平方放入result数组即可 result.append(nums[j]**2) j += 1 elif j == n: # 非负数组已经排序完,将剩下的负数数组放入result result.append(nums[i]**2) i -= 1 elif nums[i]**2 <= nums[j]**2: # 将较小的平方值放入result数组,移动指针 result.append(nums[i]**2) i -= 1 else: result.append(nums[j]**2) j += 1 return result