Amazon Interview Question
Software Engineer / DevelopersCountry: India
Interview Type: Written Test
* parse the string from right to left
* when doing so keep track of the number of zeros
* when you encounter a 1, add the current count of zeros to total counts
At the end of the loop, total counts will have the minimum number of swaps needed
this is the implementation of above logic
#include<stdio.h>
int main()
{
int arr[]={0,0,0,1,0,1,1,0,1};
int countZero = 0;
int arrSize = 9,i,j,temp,k=0;
int swap=0;
for(i=(arrSize-1);i>=0;i--)
{
if(arr[i] == 0)
{
countZero++;
}else
{
for(j=i,k=0;k<countZero;j++,k++)
{
swap++;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(i=0;i<arrSize;i++)
printf("\t%d",arr[i]);
printf("\nSwaps = %d",swap);
return 0;
}
@spider : this might help u understand
*parse the string from right to left
* when doing so keep track of the number of zeros(am using countZero variable for that)
* when you encounter a 1, add the current count of zeros to total counts (am doing it using for loop in else condition )
At the end of the loop, total counts will have the minimum number of swaps needed
The most efficient way is only when we are swapping only 0<->1 (not 0<->0 and not 1<->1)
So we have to count "1" on the left side of each "0".
public int countMoves(String stext) {
int oneCount = 0;
int result = 0;
char[] ch = stext.toCharArray();
for (int i = 0; i < ch.length; ++i) {
if (ch[i] == '1') {
oneCount++;
} else {
result += oneCount;
}
}
return result;
}
Complexity = O(n)
public static String movefront(String stext){
int end=0;
char [] ch=stext.toCharArray();
for (int i=0;i<ch.length;++i){
if (ch[i]<='0'){
ch[end]=ch[i];
end++;
}
}
for (int j=end;j<ch.length;++j){
ch[j]='1';
}
return new String(ch,0,ch.length);
}
Step 1 : Count number of 1s
for(count=0;n>0;count++) {
n&=(n-1); }
Complexity worst O(n)
Step 2: add number of 1s to a new number
n = ( 1<<(count +1) - 1);
Complexity O(1) : constant time
As mentioned by NGloom, we can just count the number of 0s during the first pass - O(n) and in the second pass set those many elements from the start as 0. the rest would be set as 1. We don't even need to swap.
the most efficient way i can think of... thinking i NEED to swap is a modified bubble sort:
int swapsDone=0;
for ( int i=0; i<n-swapsDone; i ++ )
if ( ch[i]=='1' )
for ( int j=i; j< n-swapsDone-1; j++ )
{
swap ( ch[j+1], ch[j] );
swapsDone++;
}
// i don't think i need to explain the code
well yeah! i told you its a modified bubble sort. It has to be one since you can only swap with your neighbor.
well it's your typical bubble sort, just that knowing you only have 2 values.. you can do a lot less tests:). You dont have to swap 0-s and you dont have to take each 1 to the last position. ez!
I agree with this answer. I don't think it's possbile to do better than bubble sort if you're limited to doing everything only through swaps and are further limited to only adjacent swaps.
If we want to only count the number of swaps needed, we can do much better than simulating the entire O(n^2) algorithm. We can do this in linear time. A 1 in position k (0-indexed) contributes k - x swaps, where x is the number of 1s that came before position k. As we go through the array, we'll keep track of the number of 1s we've seen so far so that the number is readily available for calculations.
what i think is there would be swaps amongs 1s also... which i guess we can avoid.... we dont need to perform swap among adjacent 1's
correct me if i am wrong
this is the implementation of above logic
#include<stdio.h>
int main()
{
int arr[]={0,0,0,1,0,1,1,0,1};
int countZero = 0;
int arrSize = 9,i,j,temp,k=0;
int swap=0;
for(i=(arrSize-1);i>=0;i--)
{
if(arr[i] == 0)
{
countZero++;
}else
{
for(j=i,k=0;k<countZero;j++,k++)
{
swap++;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(i=0;i<arrSize;i++)
printf("\t%d",arr[i]);
printf("\nSwaps = %d",swap);
return 0;
}
i think that the question has changed .......now we have to find min no. of swaps.
string s=00101. .....ans=1;
string s=001101.....ans=2;
string s=0011001......ans=4;
bool flag1=0,flag2=0;
for(int i=0,j=n-1;i<n,j>=0;i++,j--)//n =s.length();
{
if(s[i]=='0' && flag==1)
count1++;
if(s[j]=='1' && flag2==1)
count2++;
if(s[i]=='1')
flag=1;
if(s[j]=='0')
flag2=1;
}
ans=count1*count2;
this show that.........................
static int swapSort(String s) {
int i=0;
int count = 0;
int swapcount = 0;
char[] ch = s.toCharArray();
while(i<s.length()){
if(ch[i]== '1'){
count++;
i++;
}else{
swap(ch,i,count);
swapcount = swapcount+count;
if(count==0)
i++;
count=0;
}
}
return swapcount;
}
void Swap (char *str) {
if (str == NULL) return;
int flag = 1, i = 0;
/* Flag in this while loop tells us if we did a swap in the
* last pass. If we did, we go over the string again. If we
* did not see the need to do a swap in the last pass,
* then flag is zero and we are done.
*/
while (flag == 1) {
flag = 0;
i = 0;
while ( str[i + 1] ) {
if (str[i] == '1' && str[i + 1] == '0') {
str[i] = '0';
str[i + 1] = '1';
flag = 1;
i = i + 2; /* Jump two characters ahead */
}
else i++; /* Jump one */
}
}
}
Count the number of '0'(z) and '1'(o) in 1 parse. In second parse fill z '0' in beginning followed by o '1' is end
To solve the problem, we can have two pointers, one beg, and another end. Then the algorithm could be something like this :
1) Keep incrementing beg until 1 is found
2) Keep decrementing end until 0 is found.
3) flip bit at beg, flip bit at end (or swap, but just flipping would work)
4) stop when beg > end
pseudocode :
for (beg = -1, end = size; beg > end;)
while(bin_array[++beg] == '0');
while(bin_array[--end] == '1');
flip(bin_array[beg]);
flip(bin_array[end]);
In the loop, a check can be put for not continuing if beg > end :
if(beg < end)
flip(bin_array[beg])
flip(bin_array[end])
Linear time solution to find minimum no. of swaps required
public static int min_swaps(int a[]){
int min_swaps = 0;
//Find no.0f 1's
int no_of_ones = 0;
for(int lp=0;lp<a.length;lp++){
if(a[lp]==1){
no_of_ones++;
}
}
int position = a.length;
for(int lp=a.length;lp>=1;lp--){
if(a[lp-1]==1){
min_swaps+= (position - lp);
position--;
}
}
return min_swaps;
}
Linear time solution to find minimum no. of swaps
public static int min_swaps(int a[]){
int min_swaps = 0;
//Find no.0f 1's
int no_of_ones = 0;
for(int lp=0;lp<a.length;lp++){
if(a[lp]==1){
no_of_ones++;
}
}
int position = a.length;
for(int lp=a.length;lp>=1;lp--){
if(a[lp-1]==1){
min_swaps+= (position - lp);
position--;
}
}
return min_swaps;
}
parse the string from right to left
* when doing so keep track of the number of zeros
* when you encounter a 1, add the current count of zeros to total counts
At the end of the loop, total counts will have the minimum number of swaps needed
what i think is there would be swaps amongs 1s also... which i guess we can avoid.... we dont need to perform swap among adjacent 1's
correct me if i am wrong
this is the implementation of above logic
#include<stdio.h>
int main()
{
int arr[]={0,0,0,1,0,1,1,0,1};
int countZero = 0;
int arrSize = 9,i,j,temp,k=0;
int swap=0;
for(i=(arrSize-1);i>=0;i--)
{
if(arr[i] == 0)
{
countZero++;
}else
{
for(j=i,k=0;k<countZero;j++,k++)
{
swap++;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(i=0;i<arrSize;i++)
printf("\t%d",arr[i]);
printf("\nSwaps = %d",swap);
return 0;
}
public class BitSwapping {
String retStr = new String();
public int swapCtr =0;
public void arrangeBits(String inpStr){
int pos;
char temp,temp1;
String str2;
StringBuffer i_strB = new StringBuffer(inpStr);
StringBuffer strB = new StringBuffer();
//Look for 10 in the input
//Need to swap until there are no more 10s in the input
while (i_strB.indexOf("10") > 0){
pos = i_strB.indexOf("10");
temp = i_strB.charAt(pos);
temp1 = i_strB.charAt(pos+1);
str2 = i_strB.substring(pos+2);
strB = new StringBuffer(i_strB.substring(0,pos));
strB.append(temp1);
strB.append(temp);
strB.append(str2);
i_strB = strB;
swapCtr++;
}
MyPr.pln("printing output");
MyPr.pln("===============");
MyPr.pln(strB.toString());
MyPr.pln("Count of swaps "+swapCtr);
}
public static void main(String[] args){
String str = "0001111000101011";
BitSwapping bSwap = new BitSwapping();
bSwap.arrangeBits(str);
}
}
#include<stdio.h>
main()
{
int arr[8]={0,0,0,0,1,0,1,0};
//printf("enter array 8 elemenets(only 0/1):");
//scanf();
int i,j,k,zc=0,swap=0,tmp;
for(i=7;i>=0;i--)
{
if(arr[i]==0)
zc++;
else
{
for(j=i,k=0;k<zc;k++,j++)
{
swap++;
tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
}
printf("no. of swaps:%d\n",swap);
for(i=0;i<8;i++)
printf("%d",arr[i]);
}
Keep On parsing the string from left to right, and count the no of ones in a variable...
No_Of_Ones++
whenever a zero occurs
SwapNeeded+= No_Of_Ones
Here is the code:
public int SwapCounter(String bits)
{
int SwapNeeded = -1; //Error
if (bits != null && bits.length() >1)
{
int len = bits.length();
SwapNeeded = 0;
int NoOfOnes = 0;
for(int i = 0; i< len; i++)
{
String bit = bits.substring(i, i+1);
if(bit.equals("1"))
{
NoOfOnes++;
}
else if(bit.equals("0"))
{
SwapNeeded += NoOfOnes;
}
else
{
// Un supported character in the string
SwapNeeded = -1; //ErrorCode
System.out.println("Un supported character in the string");
return SwapNeeded;
}
}
}
System.out.println("No of swaps needed for stream:"+bits +" are: " + SwapNeeded);
return SwapNeeded;
}
Sorry for incomplete question, you need to give the number of swaps required.
- singh May 22, 2012