![]() |
VOOZH | about |
Given an array arr[] of integers, the task is to arrange them such that all negative integers appear before all the positive integers in the array without using any additional data structure like a hash table, arrays, etc. The order of appearance should be maintained.
Examples:
Input: arr[] = [12, 11, -13, -5, 6, -7, 5, -3, -6]
Output: [-13, -5, -7, -3, -6, 12, 11, 6, 5]
Explanation: All negative elements [-13, -5, -7, -3, -6] were arranged before positive numbers [12, 11, 6, 5] and the relative ordering was also preserved.Input: arr[] = [11, -13, 6, -7, 5]
Output: [-13, -7, 11, 6, 5]
Explanation: All negative elements [-13, -7] were arranged before positive numbers [11, 6, 5] and the relative ordering was also preserved.
Please remember:
The best time complexity that we could achieve here is O(n Log n).
Table of Content
We can modify insertion sort to solve this problem.
Traverse the array from i = 1 to n - 1.
- If the current element is positive, do nothing.
- If the current element arr[i] is negative, we insert it into sequence arr[0 .. i-1] such that all positive elements in arr[0 .. i-1] are shifted one position to their right and arr[i] is inserted at index of first positive element.
-12 -13 -5 -7 -3 -6 11 6 5
Time Complexity: O(n2)
Auxiliary Space: O(1)
The idea is to move negative elements to the prefix of the array one by one. It means first we will find and place first negative element at index 0 and then second negative element at index 1 and so on. While placing negative numbers we will shift the block of positive numbers, as a whole.
Below is an illustration of how this will happen:
Current Array: [Ln, P1, P2, P3, N1, .......], Here, Ln is the prefix subarray(can be empty) that contains only negative elements. P1, P2, P3 is the block of positive numbers and N1 is the negative number that we want to move at correct place.
In this manner, the negative numbers will be placed on the left, maintaining their relative order, while the block of all positive numbers will be shifted to the right, also preserving their relative order.
-3 -8 -7 -9 -3 -2 5 5 4 0 3 9 1
Time Complexity: O(n2)
Auxiliary Space: O(1)
Merge method of standard merge sort algorithm can be modified to solve this problem. While merging two sorted halves say left and right, we need to merge in such a way that negative part of left and right sub-array is copied first followed by positive part of left and right sub-array.
-12 -13 -5 -7 -3 -6 11 6 5
Time complexity: O(n log n).
Auxiliary Space: O(n + log n), log n, as implicit stack is used due to recursive call
The problem with the above approach is we are using an auxiliary array for merging but we're not allowed to use any data structure to solve this problem. We can do merging in place without using any data structure.
Let Ln and Lp denote the negative part and positive part of the left sub-array respectively. Similarly, Rn and Rp denote the negative and positive parts of the right sub-array respectively.
Below are the steps to convert [Ln Lp Rn Rp] to [Ln Rn Lp Rp] without using extra space, where [Ln Rn] is the negative subarray and [Ln Rn].
- Reverse Lp and Rn. We get [Lp] -> [Lp'] and [Rn] -> [Rn'] [Ln Lp Rn Rp] -> [Ln Lp’ Rn’ Rp]
- Reverse [Lp’ Rn’]. We get [Rn Lp]. [Ln Lp’ Rn’ Rp] -> [Ln Rn Lp Rp]
-12 -13 -5 -7 -3 -6 11 6 5
Time complexity: O(n log n),
Auxiliary Space: O(log n), as implicit stack is used due to recursive call