问题
Given a list of integers in sorted order, say, [-9, -2, 0, 2, 3], we have to square each element and return the result in a sorted order. So, the output would be: [0, 4, 4, 9, 81].
I could figure out two approaches:
O(NlogN)approach - We insert the square of each element in a hashset. Then copy the elements into a list, sort it and then return it.O(n)approach - If there is a bound for the input elements (say -100 to -100), then we create a boolean list of size 20000 (to store -10000 to 10000). For each of the input elements, we mark the corresponding square number as true. For e.g., for9in the input, I will mark81in the boolean array as true. Then traverse this boolean list and insert all the true elements into a return list. Note that in this we make an assumption - that there is a bound for the input elements.
Is there some way in which we could do it in O(n) time even without assuming any bounds for the input?
回答1:
Well I can think of an O(n) approach
- Split the input into 2 lists. One with negative numbers, let's call this list
A. And one with positive numbers and 0, listB. This is done while preserving the input order, which is trivial :O(n) - Reverse list
A. We do this because once squared, the greater than relation between the elements if flipped - Square every item of both list in place :
O(n) - Run a
mergeoperation not unlike that of a merge sort. :O(n) - Total:
O(n)
Done :)
回答2:
Is there some way in which we could do it in O(n) time even without assuming any bounds for the input?
Absolutely.
Since the original list is already sorted you are in luck!
given two numbers x and y
if |x| > |y| then x^2 > y^2
So all you have to do is to split the list into two parts, one for all the negative numbers and the other one for all the positive ones
Reverse the negative one and make them positive
Then you merge those two lists into one using insertion. This runs in O(n) since both lists are sorted.
From there you can just calculate the square and put them into the new list.
回答3:
We can achieve it by 2 pointer technique. 1 pointer at the start and other at the end. Compare the squares and move the pointers accordingly and start allocating the max element at the end of the new list. Time = O(n) Space = O(n)
Can you do it inplace ? To reduce space complexity.
回答4:
This can be done with O(n) time and space. We need two pointers. The following is the Java code:
public int[] sortedSquares(int[] A) {
int i = 0;
int j = A.length - 1;
int[] result = new int[A.length];
int count = A.length - 1;
while(count >= 0) {
if(Math.abs(A[i]) > Math.abs(A[j])) {
result[count] = A[i]*A[i];
i++;
}
else {
result[count] = A[j]*A[j];
j--;
}
count--;
}
return result;
}
Start from the end ad compare the absolute values. And then create the answer.
来源:https://stackoverflow.com/questions/49542410/sorted-squares-of-numbers-in-a-list-in-on