Description

The gray code is a binary numeral system where two successive values differ in only one bit.

Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.

Example 1:

Input: 2
Output: [0,1,3,2]
Explanation:
00 - 0
01 - 1
11 - 3
10 - 2

For a given n, a gray code sequence may not be uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence.

00 - 0
10 - 2
11 - 3
01 - 1

Example 2:

Input: 0
Output: [0]
Explanation: We define the gray code sequence to begin with 0.
             A gray code sequence of n has size = 2n, which for n = 0 the size is 20 = 1.
             Therefore, for n = 0 the gray code sequence is [0].

Solutions

1. Recursion

  这道题 tag 是 Backtracking,结果主要就是考察递归。

# Time: O(nlogn)
# Space: O(n)
class Solution:
    def grayCode(self, n: int) -> List[int]:
        if n==0:
            return [0]
        if n==1:
            return [0,1]
        if n==2:
            return [0,1,3,2]
        else:
            return self.grayCode(n-1) + [x + (2**(n-1)) for x in self.grayCode(n-1)[::-1]]
# Runtime: 36 ms, faster than 72.31%
# Memory Usage: 12.7 MB, less than 100.00%

2. Iterative

# Time: O(nlogn)
# Space: O(n)
class Solution:
    def grayCode(self, n: int) -> List[int]:
        if n==0:
            return [0]
        o = ['0','1'] # starting place
        i = 1 #index
        while i < n:
            L1 = o
            L2 = o[::-1]
            for s in range(len(L1)):
                L1[s] = '0'+L1[s]
            for s2 in range(len(L2)):
                L2[s2] = '1'+L2[s2]
            o = L1 + L2
            i+=1
        o = [int(j,base=2) for j in o]
        return o
# Runtime: 32 ms, faster than 87.29% 
# Memory Usage: 12.7 MB, less than 100.00%

3. Backtracking

  当然,如果愣是要用回溯做也是可以的,参考如下:

# Time: O(nlogn)
# Space: O(n)
class Solution:
    def grayCode(self, n: int) -> List[int]:
        code_size = 2 ** n
        visited = [0] * code_size
        visited[0] = 1
        res = []
        self.dfsHelper(n, visited, [0], res)
        return res[0]   
    
    def dfsHelper(self, n, visited, cur, res):
        if len(cur) == 2 ** n:
            res.append(cur[:])
            return True
        candidate = -1
        for k in range(n):
            if visited[cur[-1] ^(1 << k)] == 0:
                candidate = cur[-1] ^ (1 << k)
                break
        if candidate > 0:
            visited[candidate] = 1    
            cur.append(candidate)
            if self.dfsHelper(n, visited, cur, res):
                return
            cur.pop()
            visited[candidate] = 0
# Runtime: 24 ms, faster than 98.95% 
# Memory Usage: 14.2 MB, less than 5.26%

References

  1. 89. Gray Code