You are given an integer array nums sorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order.
Example 1:
Input: nums = [-4,-1,0,3,10]
Output: [0,1,9,16,100]Explanation: After squaring, the array becomes [16,1,0,9,100].
After sorting, it becomes [0,1,9,16,100].
Example 2:
Input: nums = [-7,-3,2,3,11]
Output: [4,9,9,49,121]Constraints:
1 <= nums.length <= 10,000-10,000 <= nums[i] <= 10,000nums is sorted in non-decreasing order.Follow up: Squaring each element and sorting the new array is very trivial, could you find an O(n) solution using a different approach?
Before attempting this problem, you should be comfortable with:
The straightforward approach is to square each element first and then sort the result. While the original array is sorted, squaring can change the order since negative numbers become positive. For example, [-4, -1, 0, 3] becomes [16, 1, 0, 9] after squaring, which needs to be sorted to [0, 1, 9, 16].
Since the input array is sorted, the largest squares will be at either end (the most negative or most positive values). By using two pointers at both ends, we can compare absolute values and always pick the larger square. This builds the result in descending order, which we then reverse.
l at the start and r at the end of the array.result list.l <= r:nums[l] and nums[r].result and move the corresponding pointer inward.result array (since we collected largest to smallest).result.This is an optimization of the previous approach that avoids the final reversal step. Instead of building the result from smallest to largest and reversing, we fill the result array from the end to the beginning. We still use two pointers to compare the absolute values at both ends, but we place each square directly in its final position.
result array of the same size as the input.l = 0, r = n - 1, and resIndex = n - 1 (pointing to the last position).l <= r:nums[l] and nums[r].res[resIndex] and move the corresponding pointer.resIndex.result array (no reversal needed).class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
res = [0] * n
l, r = 0, n - 1
res_index = n - 1
while l <= r:
if abs(nums[l]) > abs(nums[r]):
res[res_index] = nums[l] * nums[l]
l += 1
else:
res[res_index] = nums[r] * nums[r]
r -= 1
res_index -= 1
return resA common mistake is assuming that squaring a sorted array keeps it sorted. This is false when negative numbers are present because squaring makes them positive, potentially larger than squared positive numbers. For example, [-4, -1, 0, 3] becomes [16, 1, 0, 9], which is not sorted.
When using two pointers, comparing nums[l] and nums[r] directly instead of their absolute values or squares leads to incorrect results. Negative numbers at the left end may have larger squares than positive numbers at the right end, so always compare absolute values or squared values.