Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given an array of positive and negative integers, re-arrange it so that you have positive integers on one end and negative integers on other

I recently came across a Microsoft Interview Question for Software Engineer.

Given an array of positive and negative integers, re-arrange it so that you have positive integers on one end and negative integers on other, but retain their order of appearance in the original array.

For example, given [1, 7, -5, 9, -12, 15]
The answer would be: [-5, -12, 1, 7, 9, 15]

This should be done in O(n) time complexity and O(1) space complexity.

We could easily do it in O(n) time complexity, but I am not able to think how we can maintain the order of elements as in original array. If we forget about O(n) complexity, could someone tell me how we can preserve the order of elements without taking into consideration the space- and time-complexity.

like image 354
Algorithmist Avatar asked Feb 04 '11 11:02

Algorithmist


People also ask

How do you sort an array with negative and positive numbers in Javascript?

In order to sort numbers, you'll need to write a function that returns a negative number if a is less than b , returns a positive number if b is less than a , and returns 0 if the numbers are the same. This can easily be accomplished by subtracting the numbers.


1 Answers

To achieve this result in constant space (but quadratic time), you can use the two-queue approach by placing one queue at each end of the array (similar to the Dutch National Flag algorithm). Read items left-to-right : adding an item to the left queue means leaving it alone, adding an item to the right queue means shifting all elements not in a queue to the left by one and placing the added item at the end. Then, to concatenate the queues, simply reverse the order of elements in the second queue.

This performs an O(n) operation (shifting elements left) up to O(n) times, which yields an O(n²) running time.

By using a method similar to merge sort, you can achieve a lower O(n log n) complexity: slice the array in two halves, recursively sort them in the form [N P] [N P] then swap the first P with the second N in O(n) time (it gets a bit tricky when they don't have exactly the same size, but it's still linear).

I have absolutely no idea of how to get this down to O(n) time.

EDIT: actually, your linked list insight is right. If the data is provided as a doubly linked list, you can implement the two-queue strategy in O(n) time, O(1) space:

sort(list):   negative = empty   positive = empty   while (list != empty)      first = pop(list)      if (first > 0)           append(positive,first)      else          append(negative,first)   return concatenate(negative,positive) 

With a linked list implementation that keeps pointers to the first and last elements, then pop, append and concatenate are all O(1) operations, so the total complexity is O(n). As for space, none of the operations allocate any memory (append merely uses the memory released by pop), so it's O(1) overall.

like image 79
Victor Nicollet Avatar answered Nov 04 '22 15:11

Victor Nicollet