Skip to main content

Squares of a Sorted Array

Problem

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 <= 104
  • -104 <= nums[i] <= 104
  • nums is sorted in non-decreasing order.

Solution

/**
* @param {number[]} nums
* @return {number[]}
*/
var sortedSquares = function(nums) {
let split = 0; // index of first non-negative value
for (; split < nums.length && nums[split] < 0; split++);

let left = split - 1; // index for negative elements
let right = split; // index for non-negative elements
const res = [];

for (let i = 0; i < nums.length; i++) {
const val1 = Math.abs(nums[left] ?? Infinity);
const val2 = Math.abs(nums[right] ?? Infinity);

if (val1 < val2) {
res.push(val1 ** 2);
left--;
} else {
res.push(val2 ** 2);
right++;
}
}

return res;
};

We will implement a two pointers solution. Since nums is sorted in non-decreasing order, the abs of the negative values will increase as we move to the left of nums, while the positive values will increase as we move to the right of nums. Thus, we find the index split of where the values in nums changes from negative to positive, and slide outwards. Note that it might be more performant to slide inwards instead of outwards (ie. square the larger values first instead of the smaller values), as this avoids the need to compute split.