I am stuck in one interview question.. The question is,
*given two arrays A and B. A has integers unsorted. B has the same length as A and its values are in the set {-1,0,1}
you have to return an array C with the following processing on A.
if B[i] has 0 then C[i] must have A[i]
if B[i] has -1 then A[i] must be in C within the sub array C[0] - C[i-1] ie. left subarray
if B[i] has 1 then A[i] must be in C within the sub array C[i+1] - C[length(A)] ie right subarray.if no such solution exists then printf("no solution");*
I applied following logics:-
int indMinus1 = n-1;
int indPlus1 = 0;
//while(indPlus1 < n && indMinus1 > 0)
while(indPlus1 < indMinus1)
{
while(b[indMinus1] != -1) {
if(b[indMinus1] == 0)
c[indMinus1] = a[indMinus1];
indMinus1--;
}
while(b[indPlus1] != +1) {
if(b[indPlus1] == 0)
c[indPlus1] = a[indPlus1];
indPlus1++;
}
c[indMinus1] = a[indPlus1];
c[indPlus1] = a[indMinus1];
b[indMinus1] = 0;
b[indPlus1] = 0;
indMinus1--;
indPlus1++;
}
But this will not going to work,, for some cases like {1,2,3} >> {1,-1,-1}... One output is possible i.e. {2,3,1};
Please help.... does their any algorithm technique available for this problem?
Correct Solution Code
int arrange(int a[], int b[], int c[], int n)
{
for (int i = 0; i < n; ++i) {
if(b[i] == 0)
c[i] = a[i];
}
int ci = 0;
for (int i = 0; i < n; ++i) {
if(b[i] == -1) {
while(c[ci] != 0 && ci < i)
ci ++;
if(c[ci] != 0 || ci >= i)
return -1;
c[ci] = a[i];
ci++;
}
}
for (int i = 0; i < n; ++i) {
if(b[i] == 1) {
while(c[ci] != 0 && ci < n)
ci ++;
if(c[ci] != 0 || ci <= i)
return -1;
c[ci] = a[i];
ci++;
}
}
return 0;
}
I suggest the following algorithm:
1. Initially consider all C[ i ]
as empty nests.
2. For each i where B[ i ] = 0
we put C[ i ] = A[ i ]
3. Go through array from left to right, and for each i
where B[ i ] = -1
put C[ j ] = A[ i ]
, where 0 <= j < i
is the smallest index for which C[ j ]
is still empty. If no such index exists, the answer is impossible.
4. Go through array from right to left, and for each i
where B[ i ] = 1
put C[ j ] = A[ i ]
, where i < j < n
is the greatest index for which C[ j ]
is still empty. If no such index exists, the answer is impossible.
Why do we put A[ i ] to the leftmost position in step 2 ? Well, we know that we must put it to some position j < i. On the other hand, putting it leftmost will increase our changes to not get stucked in step 3. See this example for illustration:
A: [ 1, 2, 3 ]
B: [ 1, 1,-1 ]
Initially C is empty: C:[ _, _, _ ]
We have no 0-s, so let's pass to step 2.
We have to choose whether to place element A[ 2 ]
to C[ 0 ]
or to C[ 1 ]
.
If we place it not leftmost, we will get the following situation:C: [ _, 3, _ ]
And... Oops, we are unable to arrange elements A[ 0 ]
and A[ 1 ]
due to insufficient place :(
But, if we put A[ 2 ] leftmost, we will get C: [ 3, _, _ ]
,
And it is pretty possible to finish the algorithm withC: [ 3, 1, 2 ]
:)
Complexity:
What we do is pass three times along the array, so the complexity is O(3n) = O(n)
- linear.
Further example:
A: [ 1, 2, 3 ]
B: [ 1, -1, -1 ]
Let's go through the algorithm step by step:
1. C: [ _, _, _ ]
2. Empty, because no 0-s in B
3. Putting A[ 1 ]
and A[ 2 ]
to leftmost empty positions:
C: [ 2, 3, _ ]
4. Putting A[ 0 ]
to the rightmost free (in this example the only one) free position:
C: [ 2, 3, 1 ]
Which is the answer.
Source code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector< int > a;
vector< int > b;
vector< int > c;
int n;
bool solve ()
{
int i;
for( i = 0; i < n; ++i )
c[ i ] = -1;
for( i = 0; i < n; ++i )
if( b[ i ] == 0 )
c[ i ] = a[ i ];
int leftmost = 0;
for( i = 0; i < n; ++i )
if( b[ i ] == -1 )
{
for( ; leftmost < i && c[ leftmost ] != -1; ++leftmost ); // finding the leftmost free cell
if( leftmost >= i )
return false; // not found
c[ leftmost++ ] = a[ i ];
}
int rightmost = n - 1;
for( i = n - 1; i >= 0; --i )
if( b[ i ] == 1 )
{
for( ; rightmost > i && c[ rightmost ] != -1; --rightmost ); // finding the rightmost free cell
if( rightmost <= i )
return false; // not found;
c[ rightmost-- ] = a[ i ];
}
return true;
}
int main ()
{
cin >> n;
a.resize(n);
b.resize(n);
c.resize(n);
int i;
for( i = 0; i < n; ++i )
cin >> a[ i ];
for( i = 0; i < n; ++i )
cin >> b[ i ];
if( !solve() )
cout << "Impossible";
else
for( i = 0; i < n; ++i )
cout << c[ i ] << ' ';
cout << endl;
return 0;
}
Far too much time spent: ;-)
#include <stdint.h>
#include <string.h>
#include <stdio.h>
static int doit(int A[], int B[], int C[], size_t size)
{
size_t first_free = size - 1;
size_t last_free = 0;
for (size_t i = 0; i < size; ++i) {
if (B[i]) {
if (i < first_free) {
first_free = i;
}
if (i >= last_free) {
last_free = i;
}
}
}
for (int i = 0; i < size; ++i) {
if (B[i] < 0) {
if (first_free >= i) {
return 0;
}
C[first_free] = A[i];
first_free = i;
} else if (B[i] == 0) {
C[i] = A[i];
}
}
for (int i = size - 1; i >= 0; --i) {
if (B[i] > 0) {
if (last_free <= i) {
return 0;
}
C[last_free] = A[i];
last_free = i;
}
}
return 1;
}
int a[] = { 1, 2, 3 };
int b[] = { 1, -1, -1 };
int c[sizeof(a) / sizeof(int)];
int main(int argc, char **argv)
{
if (!doit(a, b, c, sizeof(a) / sizeof(int))) {
printf("no solution");
} else {
for (size_t i = 0; i < sizeof(a) / sizeof(int); ++i)
printf("c[%zu] = %d\n", i, c[i]);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With