有序数组的平方数
小于 1 分钟
题目表述
给你一个按 非递减顺序 排序的整数数组 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 已按 非递减顺序 排序
进阶:请你设计时间复杂度为 O(n) 的算法解决本问题
解法一:数组双向遍历
从中间的分界点开始,双向遍历数组,每次将平方较小者加入结果数组(Python实现)。
也可以从两边开始,从大往小添加(Go实现)
时间复杂度:O(n) 空间复杂度:O(n)
代码实现
from typing import List
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        # 储存结果数组
        ans = [0] * len(nums)
        # 查找正负数的分界点
        if nums[0] >= 0:
            zero_idx = 0
        elif nums[-1] <= 0:
            zero_idx = len(nums) - 1
        else:
            for i in range(1, len(nums)):
                if nums[i-1] * nums[i] <= 0:
                    zero_idx = i-1
                    break
        # 从零点开始双向遍历
        i, j = zero_idx, zero_idx + 1
        pidx = 0
        while i>=0 and j < len(nums):
            lval = nums[i]**2
            rval = nums[j]**2
            if lval <= rval:
                ans[pidx] = lval
                i -= 1
            else:
                ans[pidx] = rval
                j += 1
            pidx += 1
        # 单边剩余部分
        while i >= 0:
            ans[pidx] = nums[i]**2
            i -= 1
            pidx += 1
        while j < len(nums):
            ans[pidx] = nums[j]**2
            j += 1
            pidx += 1
        return ans
if __name__ == "__main__":
    nums = [-1, 2, 2]
    res = Solution().sortedSquares(nums)
    print(res)
package leetcode
func sortedSquares(nums []int) []int {
	n := len(nums)
	ans := make([]int, n)
	left, right, pidx := 0, n-1, n-1
	for left < right {
		lval := nums[left] * nums[left]
		rval := nums[right] * nums[right]
		if lval >= rval {
			ans[pidx] = lval
			left += 1
		} else {
			ans[pidx] = rval
			right -= 1
		}
		pidx -= 1
	}
	return ans
}