Sorted squares of numbers in a list in O(n)?

风格不统一 提交于 2020-03-02 16:52:29

问题


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:

  1. 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.

  2. 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., for 9 in the input, I will mark 81 in 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

  1. Split the input into 2 lists. One with negative numbers, let's call this list A. And one with positive numbers and 0, list B. This is done while preserving the input order, which is trivial : O(n)
  2. Reverse list A. We do this because once squared, the greater than relation between the elements if flipped
  3. Square every item of both list in place : O(n)
  4. Run a merge operation not unlike that of a merge sort. : O(n)
  5. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!