Amazon Interview Question
Software Engineer / DevelopersJust noticed your solution, and found our approach is same in principle. However, I used a queue to partition first array. I'm eager to hear your explanation how do you do it in O(1) space. Thanks.
I don't expect this type of question from you. As u can c that code is not using any memory that is dependent on the size of any of the array.
Both the array are sorted.
Big array contains -1 at as many places as the size of small array.
In big array to put all -1 at the end, I am swapping the -1 with first positive element which is after this current -1. So in this way all positive elements will bubble up together and all -1 will go at end.
Since for any -1 the elements before -1 are smaller than the elements after -1 and I am choosing the first positive element after -1 therefore array will remain sorted after this step.
Sorry to disappointed you. I was damn sleepy, had a quick nap, and now seems my brain is working :)
I managed it in much simpler way (before reading your reply). Here's it : ideone.com/dITsA
little simplified version of your code...
your code will fail if A[] has more memory allocated to it than the sum of size of A[](excluding all -1) + size of B[]
simple merging can be done by following code...
after assembling all -1s in the last of the array....as you have done in your code...call this function..
/*according to your code... MaxLenA=k , sizeA = i , sizeB=j */
while(MaxLenA >= 0)
{
if(sizeA < 0 || (a[sizeA] < b[sizeB]))
{
a[MaxLenA]=b[sizeB];
sizeB--;
}
else
{
a[MaxLenA]=a[sizeA];
sizeA--;
}
MaxLenA--;
}
<pre lang="" line="1" title="CodeMonkey68729" class="run-this">#include <stdio.h>
void merge(int A[], unsigned int lA, int B[], unsigned int lB)
{
int i = 0, j = 0, k = 0;
while (k < lA) {
while (A[i] < 0)
i++;
if (i == lA)
A[k++] = B[j++];
else if (j == lB)
A[k++] = A[i++];
else if (A[i] < B[j])
A[k++] = A[i++];
else
A[k++] = B[j++];
}
}
int main()
{
int A[] = { -1, -1, 8, 19, -1, -1, -1, 31, -1, 38, 65, -1, 85, -1, -1, 110, 150, -1};
int B[] = {24, 51, 90, 130, 140, 180, 190, 220, 250, 260};
int i = 0;
merge(A, sizeof(A) / sizeof(int), B, sizeof(B) / sizeof(int));
while (i < (sizeof(A) / sizeof(int))) {
printf("[%d]", A[i]);
i++;
}
printf("\n");
}
</pre><pre title="CodeMonkey68729" input="yes">
</pre>
It seems same as its trivial counterpart. Start merging arrays from the back, means start comparing from the highest elements of both arrays.
1) i = m-1 and j = k = n-1.
while(A[j]==-1) j--
2) run loop till k>=0
3) if(A[j] == B[i]) A[k] = A[k-1] = A[j];
k = k-2; i--; while(A[j]==-1) j--;
4) else if(A[j] > B[j]) A[k] = A[j];
k--; while(A[j]==-1) j--;
5) else A[k] = B[i];
k--; i--;
Using a deque (to keep track of sorted index of -1), array A can be rearranged such that all -1s are at end, and the rest are sorted. It takes O(n) time.
Now, merge from back.
<pre lang="" line="1" title="CodeMonkey88818" class="run-this">/* The class name doesn't have to be Main, as long as the class is not public. */
class Main
{
public static void merge(int[] big, int[] small) {
if (big == null || small == null) {
return;
}
// Shift all positive numbers in bigger array to right. keep them sorted.
for (int i = big.length - 1, j = i; j >= small.length; i--) {
if (big[i] > 0) {
big[j--] = big[i];
}
}
// Merge till the small array is exhausted.
for (int i = 0, pBig = small.length, pSmall = 0; pSmall < small.length; i++) {
if (pBig >= big.length) {
big[i] = small[pSmall++];
} else {
big[i] = big[pBig] <= small[pSmall] ? big[pBig++] : small[pSmall++];
}
}
}
public static void main (String[] args) throws java.lang.Exception {
int[] big = {2, -1, 7, -1, 10, -1, 11, -1, 18, -1, 22, -1, 24, -1, 27, -1, 29};
int[] small = {4, 13, 24, 27, 28, 28, 30, 30};
System.out.println(Arrays.toString(big));
System.out.println(Arrays.toString(small));
merge(big, small);
System.out.println(Arrays.toString(big));
}
}
</pre><pre title="CodeMonkey88818" input="yes">
</pre>
void mergeArrays(int* a, int sizeOfa, int* b, int sizeOfb)
{
int i = sizeOfa - 1;
int j;
int x = i;
while (a[i] != -1 && i >=0) {
i--;
x--;
}
while (i >= 0) {
while (a[i] == -1)
i--;
if (i >= 0) {
exchange(a, i, x);
i--;
x--;
}
}
i = x + 1;
x = 0;
j = 0;
while (j < sizeOfb && i < sizeOfa) {
if (a[i] <= b [j]) {
exchange(a, x, i);
x++;
i++;
}
else {
a[x] = b[j];
x++;
j++;
}
}
while (j < sizeOfb) {
a[x] = b[j];
x++;
j++;
}
}
Time O(n), space O(1)
- Anonymous June 26, 2011