## 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: 
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 .


## Solutions

### 1. Recursion

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

# Time: O(nlogn)
# Space: O(n)
class Solution:
def grayCode(self, n: int) -> List[int]:
if n==0:
return 
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 
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 =  * code_size
visited = 1
res = []
self.dfsHelper(n, visited, , res)
return res

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%