Given an array of numbers sorted in increasing order, return a new array containing squares of all the numbers of the input array sorted in increasing order.
If the array only had positive integers, then we could just square it and return the squared array as output. The only caveat with this question is that it has negative integers as well.
But if we can view the negative part and positive part of the array separately, and iterate over both the parts then we can get the squared array in O(n) time complexity.
Here is how the approach will work:
Find the index of the first non-negative number in the array.
Use two pointers to iterate over the array - one pointer will move forward to iterate over the non-negative numbers, and the other pointer will move backward to iterate over the negative numbers.
At any step, we check which pointer gives a smaller square. We add the smaller square to the output array and advance the corresponding pointer.
publicint[]sortedSquares(int[] nums) {
int n = nums.length;
int[] squaredArr =newint[n];
// Find the index of first non-negative elementint firstNonNegIdx = n;
for (int i = 0; i < n; i++) {
if (nums[i]>= 0) {
firstNonNegIdx = i;
break;
}
}
// Pointer to iterate over the negative elementsint negItr = firstNonNegIdx - 1;
// Pointer to iterate over the non-negative elementsint posItr = firstNonNegIdx;
int sqrIdx = 0;
while (negItr >= 0 && posItr < n) {
int negElementSquare = nums[negItr]* nums[negItr];
int posElementSquare = nums[posItr]* nums[posItr];
if (negElementSquare < posElementSquare) {
squaredArr[sqrIdx++]= negElementSquare;
negItr--;
} else {
squaredArr[sqrIdx++]= posElementSquare;
posItr++;
}
}
// Add the square of remaining negative elements to the outputwhile (negItr >= 0) {
squaredArr[sqrIdx++]= nums[negItr]* nums[negItr];
negItr--;
}
// Add the square of the remaining positive elements to the outputwhile (posItr < n) {
squaredArr[sqrIdx++]= nums[posItr]* nums[posItr];
posItr++;
}
return squaredArr;
}
An alternate two pointer approach is to use two pointers - one starting from the rightmost element of the array and the other starting from the leftmost element.
1
2
pointer1→ ←pointer2
[-5, -2, -1, 0, 4, 6]
At every step, check which pointer gives the highest square. Add the highest square to the output array (starting from right) and advance the corresponding pointer.
publicint[]sortedSquares(int[] nums) {
int n = a.length;
int[] squaredArr =newint[n];
int highestSquareIdx = n - 1;
int left = 0;
int right = n - 1;
while (left <= right) {
int leftSquare = a[left]* a[left];
int rightSquare = a[right]* a[right];
if (leftSquare > rightSquare) {
squaredArr[highestSquareIdx--]= leftSquare;
left++;
} else {
squaredArr[highestSquareIdx--]= rightSquare;
right--;
}
}
return squaredArr;
}