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
This solution has O(n) time complexity and O(1) space complexity
Idea is:
keep track of index of last seen negative element (lastNegIndex).
loop through the array to find negative elements that are preceded by positive element.
If such element is found, right rotate elements between lastNegIndex and current Index by one. Then update lastNegIndex (it will be next index).
Here is the code:
public void rightRotate(int[] a, int n, int currentIndex, int lastNegIndex){
int temp = a[currentIndex];
for(int i = currentIndex; i > lastNegIndex+ 1; i--){
a[i] = a[i-1];
}
a[lastNegIndex+1] = temp;
}
public void ReArrange(int[] a, int n){
int lastNegIndex= -1;
int index;
if(a[0] < 0)
lastNegIndex = 0;
for(index = 1; index < n; index++){
if (a[index] < 0 && a[index - 1] >= 0) {
rightRotate(a, n, index, lastNegIndex);
lastNegIndex = lastNegIndex + 1;
}
}
}
I hope this helps. This one has Time Complexity O(n^2)
#include <stdio.h>
int main() {
int a[] = {-3, 2, -5, 9, -2, -8, 6, 8, -1, 6};
int length = (sizeof(a) / sizeof(int));
int i, j = 0;
printf("Size of array: %d\n", sizeof(a));
for (i = 0; i < length; i++) {
if (i % 2 == 0 && a[i] < 0) {
for (j = i + 1; j < length; j++) {
if (a[j] > 0) {
int t = a[i];
a[i] = a[j];
a[j] = t;
break;
}
}
} else if (i % 2 == 1 && a[i] > 0) {
for (j = i + 1; j < length; j++) {
if (a[j] < 0) {
int t = a[i];
a[i] = a[j];
a[j] = t;
break;
}
}
}
}
for (i = 0; i < length; i++) {
printf("Value at %d: %d\n", i, a[i]);
}
return 0;
}
EDIT 1 This relies on the fact that numbers greater than zero are always at an even index and numbers less than zero are always at odd index
EDIT 2 Improved the code a little
Just an idea.. Let's consider a simplier problem:
Given an array, where first part (Np
elements) contains only positive numbers, and last part (Nn
elements): only negative ones.
How to swap these parts while mainaning the relative order?
Simpliest solution is to use inversion:
inverse(array, Np + Nn); // whole array
inverse(array, Nn); // first part
inverse(array+Nn, Np); // second part
It has O(n) time complexity and O(1) space complexity.
Here is a JavaScript implementation of qiwangcs's solution:
function specialSort(A){
let min = Number.MAX_SAFE_INTEGER, max = -Number.MAX_SAFE_INTEGER;
for(let i=0; i<A.length; i++){
if(A[i] > max)
max = A[i];
if(A[i] < min)
min = A[i];
}
//Change all values to Positive
for(let i=0; i<A.length; i++)
A[i]-= min;
const newMax = max-min+1;
//Save original negative values into new positions
let currNegativeIndex = 0;
for(let i=0; i<A.length; i++)
if(A[i]%newMax < (-min))
A[currNegativeIndex++] += (A[i]%newMax)*newMax;
//Save original positive values into new positions
let currPositiveIndex = currNegativeIndex;
for(let i=0; i<A.length; i++)
if(A[i]%newMax > (-min))
A[currPositiveIndex++] += (A[i]%newMax)*newMax;
//Recover to original value
for(let i=0; i<A.length; i++){
A[i] = Math.floor(A[i]/newMax) + min;
}
}
// Demo
const A = [-3,-7,2,8,-5,-2,4];
specialSort(A);
console.log(A);
This code Work with O(n) complexity and O(1) space. No need to declare another array.
#include <stdio.h>
int* sort(int arr[], int size)
{
int i;
int countNeg = 0;
int pos = 0;
int neg = 0;
for (i = 0; i < size; i++)
{
if (arr[i] < 0)
pos++;
}
while ((pos < (size-1)) || (neg < size-(pos-1)))
{
if ((arr[pos] < 0) && (arr[neg] > 0))
{
arr[pos] = arr[pos] + arr[neg];
arr[neg] = arr[pos] - arr[neg];
arr[pos] = arr[pos] - arr[neg];
pos++;
neg++;
continue;
}
if ((arr[pos] < 0) && (arr[neg] < 0))
{
neg++;
continue;
}
if ((arr[pos] > 0) && (arr[neg] > 0))
{
pos++;
continue;
}
if ((arr[pos] > 0) && (arr[neg] < 0))
{
pos++;
neg++;
continue;
}
}
return arr;
}
void main()
{
int arr[] = { 1, 7, -5, 9, -12, 15 };
int size = sizeof(arr) / sizeof(arr[0]);
sort(arr, size);
int i;
for (i = 0; i < size; i++)
{
printf("%d ,", arr[i]);
}
printf(" \n\n");
}
I've tried with the bubble sorting method and it works perfectly and it retain their order of appearance in the original array.
int main()
{
int array[TAM], num, i=0, j=0;
printf("Ingrese arreglo: ");
for(i=0; i < TAM -1 && num != 0; i++)
{
scanf("%d", &num);
array[i]=num;
}
for(i=0; array[i] != 0 ; i++)
{
j++;
}
Alternar(array, j);
//MOSTRAR
for(i=0; i < j; i++)
{
printf("%d ", array[i]);
}
return 0;
}
void Alternar(int array[], int j)
{
int i=0, aux, pasadas=1;
for(pasadas=1; pasadas < j; pasadas++)
{
for(i=0; i < j - pasadas ; i++)
{
if(array[i] > 0 && array[i+1] < 0)
{
aux = array[i];
array[i] = array[i+1];
array[i+1] = aux;
}
}
}
}