Question: 977. Squares of a Sorted Array
Given an integer array nums sorted in non-decreasing order, return an array of the squares of each number 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?
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]
First attempt: using bubble sort
- My initial thought was 'do I have to sort this before or after squaring each number? which sort method would be efficient?'
- To make it less than O(N2), it seemed like I have use heap sort. But heap sort still is not O(N), which follow-up question prefers. It is O(n*logn).
- For here, though I knew that bubble sort is O(N2), I just wanted to practice bubble sort, which is one of the simple sorts we usually first learn.
Second attempt: using two pointers and aim O(N)
- It seemed like I can take an advantage of non-decreasing order.
- I tried to think of ways, asking
how to move a negative number or its squared value to the correct position?
- It seemed like I had to compare the value of
square(positive num) vs. square(negative num)
- I also referred to this post at the end to refine my solution.
- In this solution, it adds bigger squared(value) to a beginning of
result array
. And then reverse theresult array
at the end to make it *non-decreasing order. - In my solution, I started adding squared(value) from the end of
result array
. And then make it to its index 0. - Here, I first thought I can use
upper_index
as and index for adding new item toresult array
. But two different conditional cases returned different outcomes. So I createdlast_index
variable to be clear and working for both cases.
Psuedo code
var sortedSquares = function(nums) {
// 2. O(n) with two pointers
// #1. if all nums are positive, just return simple squared result.
// #2. if there's negative nums, we need two pointers leftmost, rightmost
// similar to binary search two pointers.
// compare two pointers' squared values
// and add bigger number to the end of the list, aka at upper_bound index.
let lower_bound = 0;
let upper_bound = nums.length - 1;
let reordered_arr = [];
while(lower_bound <= upper_bound) {
// if lower val is bigger than upper val
// add lower(bigger) val to upper index of new arr
// move lower index + 1
// if upper val is bigger than lower val
// add upper(bigger) val to upper index of new arr
// move upper index - 1
}
return reordered_arr;
};
Final code
var sortedSquares = function(nums) {
// 2. O(n) with two pointers
// #1. if all nums are positive, just return simple squared result.
let has_negative = false;
for(let i = 0; i < nums.length; i++) {
if(nums[i] < 0) {
has_negative = true;
break;
}
}
if(!has_negative) {
let squared_arr = [];
for(let i = 0; i < nums.length; i++) {
squared_arr.push(nums[i]*nums[i]);
}
return squared_arr;
}
// #2. if there's negative nums, we need two pointers leftmost, rightmost
let lower_bound = 0;
let upper_bound = nums.length - 1;
let reordered_arr = [];
let last_index = upper_bound;
while(lower_bound <= upper_bound) {
if(nums[lower_bound]*nums[lower_bound] >= nums[upper_bound]*nums[upper_bound]) {
reordered_arr[last_index] = nums[lower_bound]*nums[lower_bound];
lower_bound += 1;
} else if(nums[upper_bound]*nums[upper_bound] > nums[lower_bound]*nums[lower_bound]) {
reordered_arr[last_index] = nums[upper_bound]*nums[upper_bound];
upper_bound -= 1;
}
last_index -= 1;
// i initially put the squared num to [upper_bound] index, but it messes the insertion.
// using last_index is more clear
}
return reordered_arr;
};
Top comments (0)