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
here my answer is two separate positive and negative values in single array it will help you
int[] singleArray= {300, -310, 320, 340, 350,
-330, 420, 370, -360, 390,
340, -430, 320, -463, 450};
public double[] getPositive_SingleArray() {
double minValue = 0;
double positiveValue=0;
int count=0;
for (int i = 0; i < singleArrayData.length; i++) {
if ( singleArrayData[i]>0)
count++;
}
positiveSingleArrayData=new double[count];
int k=0;
for (int i = 0; i < singleArrayData.length; i++) {
if ( singleArrayData[i]>0){
positiveSingleArrayData[k] = singleArrayData[i];
k++;
}
}
System.out.println("single array of positve values "+Arrays.toString(positiveSingleArrayData));
return positiveSingleArrayData;
}
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.
#include <iostream>
using namespace std;
void negativeFirst_advanced (int arr[ ], int size)
{
int count1 =0, count2 =0;
while(count2<size && count1<size)
{
if(arr[count1]>0 && arr[count2]<0)
{
int temp = arr[count1];
arr[count1] = arr[count2];
arr[count2] = temp;
}
if (arr[count1]<0)
count1++;
if (arr [count2]>0)
count2++;
}
}
int main()
{
int arr[6] = {1,7,-5,9,-12,15};
negativeFirst_advanced (arr, 6);
cout<<"[";
for (int i =0; i<6;i++)
cout<<arr[i]<<" , ";
cout<<"]";
system("pause");
return 0;
}
A simple and easy solution which works in O(n) time complexity.
int left = 0;
int right = arr.length - 1;
while (left < right) {
while (arr[left] >= 0) {
left++;
}
while (arr[right] < 0) {
right--;
}
if (left < right) {
ArrayUtility.swapInArray(arr, left, right);
}
ArrayUtility.printArray(arr);
This is not Complexity O(1) but a simpler approach. Do comment
void divide (int *arr, int len) {
int positive_entry_seen = 0;
for (int j = 0; j < len ; j++) {
if (arr[j] >= 0 ) {
positive_entry_seen = 1;
} else if ((arr[j] < 0 ) && positive_entry_seen) {
int t = arr[j];
int c = j;
while ((c >= 1) && (arr[c-1] >= 0)) {
arr[c] = arr[c-1];
c--;
}
arr[c] = t;
}
}
}
This uses partition process of QuickSort. The time complexity of this solution is O(n2) and auxiliary space is O(1). This approach maintains the order of appearance and have not used any other data structure. This is in Ruby
def sortSeg(intArr)
intArr.each_with_index do |el, idx|
# if current element is pos do nothing if negative,
# shift positive elements of arr[0..i-1],
# to one position to their right */
if el < 0
jdx = idx - 1;
while (jdx >= 0 and intArr[jdx] > 0)
intArr[jdx + 1] = intArr[jdx];
jdx = jdx - 1;
end
# Insert negative element at its right position
intArr[jdx + 1] = el;
end
end
end