一、算法说明
n位格雷码序列是一个由 2 n 2^n 2n 个整数组成的序列,其中:
- 每个整数都在范围 [ 0 , 2 n − 1 ] [0,2^{n-1}] [0,2n−1]内(含 0 0 0和 2 n − 1 2^{n-1} 2n−1)
- 第一个整数是 0 0 0
- 一个整数在序列中出现不超过一次
- 每对相邻整数的二进制表示恰好一位不同
- 第一个和最后一个整数的二进制表示恰好一位不同
二、算法示例
示例1:
输入: n = 2 n=2 n=2
输出: [ 0 , 1 , 3 , 2 ] [0, 1, 3, 2] [0,1,3,2]
解释:
[ 0 , 1 , 3 , 2 ] [0,1,3, 2] [0,1,3,2]的二进制表示是 [ 00 , 01 , 11 , 10 ] [00,01,11,10] [00,01,11,10]。
- 00 00 00和 01 01 01有一位不同
- 01 01 01和 11 11 11有一位不同
- 11 11 11和 10 10 10有一位不同
- 10 10 10和 00 00 00有一位不同
[ 0 , 2 , 3 , 1 ] [0,2,3,1] [0,2,3,1]也是一个有效的格雷码序列,其二进制表示是 [ 00 , 10 , 11 , 01 ] [00,10,11,01] [00,10,11,01]。
- 00 00 00和 10 10 10有一位不同
- 10 10 10和 11 11 11有一位不同
- 11 11 11和 01 01 01有一位不同
- 01 01 01和 00 00 00有一位不同
示例2:
输入: n = 1 n=1 n=1
输出: [ 0 , 1 ] [0, 1] [0,1]
三、算法分析
格雷码序列我们可以这样理解,把 [ 0 , 2 n − 1 ] [0, 2^{n - 1}] [0,2n−1] 中所有数字串成一个环,环中每相邻两数字的二进制位有且仅有一位不同。其中格雷码的第一个整数是 0 0 0 。 n n n到 n + 1 n+1 n+1位格雷码的推导总结如下:
- 1 1 1位格雷码只有 0 0 0和 1 1 1两个数字。
- n n n位格雷码在前面加上 0 0 0就是 n + 1 n+1 n+1位格雷码的前半部分。
- n n n位格雷码的逆序,在前面加上 1 1 1就是 n + 1 n+1 n+1位格雷码的后半部分。
四、Python代码
def grayCode(n):
if n == 1:
return [0, 1]
pre_res = grayCode(n-1)
res = []
res = [(1<<(n-1)) + i for i in pre_res[::-1]]
return pre_res + res
print(grayCode(2)) # [0, 1, 3, 2]
一点就通:
运算符 | 举例 | |
---|---|---|
左移位运算(<<) | 假设我们有一个二进制数 num=0b1010,执行左移 2 位操作,得到0b101000 | num << 2 |
右移位运算(>>) | 假设我们有一个二进制数 num=0b1010,执行右移 1 位操作,得到0b101 | num >> 1 |