-2

I have some code here that where x grows like big O(n), however I'm not sure why. It seems more of a logarithmic big O. Could I get some help figuring out why it grows like big O(n)? Thanks!

      i = k;    x = 1.0;
  while (i > 1 ) {
    i = (int) Math.floor( i / 2.0 );
    x = x *2  ; 

2 Answers2

3

Complexity analysis has little to do with what value ends up in a variable, it a property of an algorithm, simplistically (for time complexity) how many steps it needs to do based on some input value.

In this case, given the input value k, your complexity is O(log N) because the division by two "halves the remaining solution space" on each iteration, along the lines of:

i = 128 64 32 16 8 4 2 1

The growth of the variable x which, as mentioned, has nothing to do with the algorithmic complexity, is to double each time through the loop.

So, you have a loop controlled by a value that halves on each iteration. And you have a variable that doubles on each iteration:

i = 128 64 32 16  8  4  2   1
 x =  1  2  4  8 16 32 64 128

Hence it makes sense that the relationship between the input value and the final variable value will be a linear one, as shown by the equivalent Python code:

ctrl = 1024
other = 1
while ctrl > 0:
    print('{0:4d} {1:4d}'.format(ctrl, other))
    ctrl = ctrl // 2
    other = other * 2

which outputs:

1024    1
 512    2
 256    4
 128    8
  64   16
  32   32
  16   64
   8  128
   4  256
   2  512
   1 1024

Note there that, though the final value in other is 1024, only ten "steps" were executed, since log21024 is 10.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
2

If you're looking to optimize the problem, it looks like you're just calculating the largest bit

This can also be achieved a bit more efficiently with Integer.highestOneBit(int i)

Which is defined as

public static int highestOneBit(int i) {
    // HD, Figure 3-1
    i |= (i >>  1);
    i |= (i >>  2);
    i |= (i >>  4);
    i |= (i >>  8);
    i |= (i >> 16);
    return i - (i >>> 1);
}

and should be running in constant time (O(1)) since it is only bit operators

How it works is by shifting the bits down while ORing it with itself, causing all of the bits past the largest to become 1, then to isolate the largest it subtracts that number shifted over to remove all the trailing 1s

phflack
  • 2,729
  • 1
  • 9
  • 21
  • Although, technically, I think if you're allowed to limit the input value, the *original* algorithm is O(1) as well :-) But this one would be far more efficient in runtime (rather than complexity). – paxdiablo Oct 23 '15 at 03:13
  • @paxdiablo True, if you treat it as a function given random numbers it should be about O(1), since more numbers doesn't take longer, just on their testing set (0-max int?) it's O(lg(N)) – phflack Oct 23 '15 at 03:17
  • In any case, you've almost certainly seen through the XY nature of the question so that deserves a vote. – paxdiablo Oct 23 '15 at 03:21