1

The following Gray Code algorithm is taken from the Elements of Programming Interviews book. Given a partially built result in which all pairs of adjacent elements differ at most in one bit, it computes the next element by changing one bit of the last element on the list and making a recursive call.

How would one estimate its running time? My intuition is that there're 2^n elements in the result, each takes at least constant time and at most O(n) to compute, so the lower bound would be at least 2^n. Is it correct at all? How do I calculate the upper bound on the running time considering the backtracking - some computations don't finish, how do I factor that in?

public static List<Integer> grayCode(int numBits) {
    List<Integer> result = new ArrayList<>(List.of(0));
    directedGrayCode(numBits, new HashSet<Integer>(List.of(0)), result);
    return result;
  }

  private static boolean directedGrayCode(int numBits, Set<Integer> history, List<Integer> result) {
    if (result.size() == (1 << numBits)) {
      return differsByOneBit(result.get(0), result.get(result.size() - 1));
    }

    for (int i = 0; i < numBits; ++i) {
      int previousCode = result.get(result.size() - 1);
      int candidateNextCode = previousCode ^ (1 << i);
      if (!history.contains(candidateNextCode)) {
        history.add(candidateNextCode);
        result.add(candidateNextCode);
        if (directedGrayCode(numBits, history, result)) {
          return true;
        }
        result.remove(result.size() - 1);
        history.remove(candidateNextCode);
      }
    }
    return false;
  }

  private static boolean differsByOneBit(int x, int y) {
    int bitDifference = x ^ y;
    return bitDifference != 0 && (bitDifference & (bitDifference - 1)) == 0;
  }
super.t
  • 2,526
  • 7
  • 32
  • 51

0 Answers0