🧠
Two Pointers from Ends (Merge-like)
💡 This approach leverages the sorted property of the input array and the fact that the largest squares come from the largest absolute values at the ends.
Intuition
Use two pointers at the start and end of the array, compare absolute values, and fill the output array from the end to the start.
Algorithm
- Initialize two pointers: left at 0, right at n-1.
- Create an output array of the same size.
- Iterate from the end of the output array to the start:
- Compare absolute values at left and right pointers, square the larger, place it at current position, and move that pointer.
💡 This algorithm is efficient but requires careful pointer management and filling the output array backwards.
def sortedSquares(nums):
n = len(nums)
result = [0] * n
left, right = 0, n - 1
for i in range(n - 1, -1, -1):
if abs(nums[left]) > abs(nums[right]):
result[i] = nums[left] * nums[left]
left += 1
else:
result[i] = nums[right] * nums[right]
right -= 1
return result
# Driver code
if __name__ == '__main__':
nums = [-4,-1,0,3,10]
print(sortedSquares(nums))
Line Notes
n = len(nums)Store length for convenience
result = [0] * nPre-allocate output array for efficiency
left, right = 0, n - 1Initialize pointers at array ends
for i in range(n - 1, -1, -1)Fill output array from end to start
import java.util.*;
public class Solution {
public static int[] sortedSquares(int[] nums) {
int n = nums.length;
int[] result = new int[n];
int left = 0, right = n - 1;
for (int i = n - 1; i >= 0; i--) {
if (Math.abs(nums[left]) > Math.abs(nums[right])) {
result[i] = nums[left] * nums[left];
left++;
} else {
result[i] = nums[right] * nums[right];
right--;
}
}
return result;
}
public static void main(String[] args) {
int[] nums = {-4,-1,0,3,10};
System.out.println(Arrays.toString(sortedSquares(nums)));
}
}
Line Notes
int[] result = new int[n];Allocate output array to store squares
int left = 0, right = n - 1;Set pointers at both ends of input
for (int i = n - 1; i >= 0; i--) {Fill output from last index backwards
if (Math.abs(nums[left]) > Math.abs(nums[right])) {Compare absolute values to decide which square is larger
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector<int> result(n);
int left = 0, right = n - 1;
for (int i = n - 1; i >= 0; i--) {
if (abs(nums[left]) > abs(nums[right])) {
result[i] = nums[left] * nums[left];
left++;
} else {
result[i] = nums[right] * nums[right];
right--;
}
}
return result;
}
int main() {
vector<int> nums = {-4,-1,0,3,10};
vector<int> res = sortedSquares(nums);
for (int val : res) cout << val << ' ';
cout << endl;
return 0;
}
Line Notes
vector<int> result(n);Pre-allocate vector for output
int left = 0, right = n - 1;Initialize pointers at array ends
for (int i = n - 1; i >= 0; i--) {Fill output array backwards
if (abs(nums[left]) > abs(nums[right])) {Compare absolute values to pick larger square
function sortedSquares(nums) {
const n = nums.length;
const result = new Array(n);
let left = 0, right = n - 1;
for (let i = n - 1; i >= 0; i--) {
if (Math.abs(nums[left]) > Math.abs(nums[right])) {
result[i] = nums[left] * nums[left];
left++;
} else {
result[i] = nums[right] * nums[right];
right--;
}
}
return result;
}
// Test
console.log(sortedSquares([-4,-1,0,3,10]));
Line Notes
const result = new Array(n);Allocate output array with fixed size
let left = 0, right = n - 1;Initialize pointers at both ends
for (let i = n - 1; i >= 0; i--) {Fill output array from end to start
if (Math.abs(nums[left]) > Math.abs(nums[right])) {Compare absolute values to decide which square to place
We traverse the array once with two pointers, performing constant work per element.
💡 For n=1000, this means about 1000 operations, which is very efficient.
Interview Verdict: Accepted and optimal
This approach is the best practical solution and is expected in interviews.