Arrange 0's & 1's in a array

前端 未结 16 1969
独厮守ぢ
独厮守ぢ 2020-12-04 13:36

This is one of an interview question which I had recently. I would like to know others perception of approach for this problem.

Question:

Yo

相关标签:
16条回答
  • 2020-12-04 14:09

    My implementation in Perl using simple weighting.

    use Modern::Perl;
    
    my @data;
    {
      use List::MoreUtils qw'natatime';
      my $iter = natatime 2, qw'
        X1  0
        X2  1
        X3  0
        X4  1
        X5  0
      ';
    
      while( my($a,$b) = $iter->() ){
        push @data, [$a,$b]
      }
    }
    
    my @sorted = sort {
      ($a->[1] <=> $b->[1]) * -2 + # gives more weight to second element
      ($a->[0] cmp $b->[0])
    } @data;
    
    say "Name\tDept\n";
    say join "\t", @$_ for @sorted;
    
    Name    Dept
    
    X2      1
    X4      1
    X1      0
    X3      0
    X5      0
    

    The output of <=> and cmp comparisons is a value of -1,0,1.
    By multiplying one of the camparisons by two we get one of -2,0,2.
    After adding the value of the other operator we get one of -3,-2,-1,0,1,2,3

    I wanted to see how many comparisons it would do so I added some debugging information and came up with this.

     a           b        a1      b1     a0     b0
    X1,0   ->   X2,1      0   --> 1      X1 <-  X2
    X3,0   ->   X4,1      0   --> 1      X3 <-  X4
    X2,1  <-    X4,1      1   -   1      X2 <-  X4
    X4,1  <-    X1,0      1 <--   0      X4  -> X1
    X1,0  <-    X3,0      0   -   0      X1 <-  X3
    X2,1 <<-    X5,0      1 <--   0      X2 <-  X5
    X5,0   ->>  X4,1      0   --> 1      X5  -> X4
    X5,0   ->   X1,0      0   -   0      X5  -> X1
    X5,0   ->   X3,0      0   -   0      X5  -> X3
    
    The arrows point at the earlier value.
    
    0 讨论(0)
  • 2020-12-04 14:10

    The original problem text didn't mention any other fields except the integer (has been edited since then).

    In such case stability has no sense since two equal numbers are otherwise indistinguishable. The solution is to just traverse the array and put 1's n/2 times and then 0's n/2 times.

    0 讨论(0)
  • 2020-12-04 14:10

    I can think of an algorithm which will take O(n + i) time (worst case O(2n-1) and best case O(n)) and no extra space. We start traversing the array from 0 to n-1 and each time we encounter a 1 we increment a counter and replace that 1 with 0. Now when we have reached the end of the array we will start moving backwards as much is counter and initialize each number with 1.

    private static int[] foo(int[] array) {
    
    int counter = 0;
    int i;
    
    for(i = 0; i < array.length; i++) {
    if (array[i] == 1) {
        array[i] = 0;
        counter++;      
    }
    }
    
    while(counter > 0) {
    array[--i] = 1;
    counter--;
    }
    return array;
    }
    
    0 讨论(0)
  • 2020-12-04 14:12

    Used ints instead of bits for simplicity but the underlying concept is the same. Not that the order the different 1s and 0s end up in matters!

    var emps = new[] 
               {
                   new Employee(X1, 0),
                   new Employee(X2, 1),
                   new Employee(X3, 0),
                   new Employee(X4, 1),
                   new Employee(X5, 0),
                   new Employee(X6, 1)
               };
    
    var sortedEmps = new Employee[bits.Length];
    
    var oneIndex = 0;
    var zeroIndex = bits.Length/2;
    
    foreach (var employee in employees)
    {
        if (employee.Dept  == 1)
            sortedEmps[oneIndex++] = employee;
        else
            sortedEmps[zeroIndex++] = employee;
    }
    

    Updated to do the employees problem. Added an extra employee as the original question said there were N/2 of each so there has to be an even number for that to be true. Otherwise it's the same.

    Not sure this compiles now so treat it as pseudo code!

    0 讨论(0)
  • 2020-12-04 14:15

    using std::stable_partition together with std::equal_to and std::binder1st should do the trick in a nice, functional, STL-like way:

    using namespace std
    stable_partition(&array[0], &array[N], binder1st(equal_to(), 1));
    

    Of course, this assumes that the elements of array have some comparison operator defined (i.e. you can say array[i]==1...). If they are just integers, it wouldn't make any sense to maintain the order ...

    As to complexity: In order to be O(N), stable_partition needs extra memory. If the algorithm fails to allocate that extra memory, it performs in O(N log N).

    0 讨论(0)
  • 2020-12-04 14:19
    #include<stdio.h>
    //#include<conio.h>
    
    int main()
    {
      int i,a[20]={0};
      int *ptr1,*ptr2;
      //clrscr();
      //a[2]=a[4]=a[6]=a[8]=a[16]=1;
      a[19]=a[18]=1;
    
      for(i=0;i<20;i++)
        printf("%d",a[i]);
    
      printf("\n\nafter");
    
      ptr1=ptr2=a;
      for(i=0;i<20;i++)
      {
        if(*ptr1==0&&*ptr2==1)
        {
          int temp=*ptr1;*ptr1=*ptr2;*ptr2=temp;
          ptr1++;ptr2++;
        }
        else if(*ptr1==1&&*ptr2==0)
        {
          ptr1++;ptr2++;
        }
        else if(*ptr1==0&&*ptr2==0)
        {
          ptr2++;
        }
        else
        {
          if(ptr1<ptr2)
            ptr1++;
          else
          {
            ptr1++;ptr2++;
          }
        }
      }
    
      for(i=0;i<20;i++)
      {
        printf("%d",a[i]);
      }
    
     // getch();
    
      return 0;
    }
    
    0 讨论(0)
提交回复
热议问题