一、题目描述
n
位格雷码序列 是一个由 2n
个整数组成的序列,其中:
每个整数都在范围 [0, 2^n - 1]
内(含 0
和 2^n - 1
)
第一个整数是 0
一个整数在序列中出现 不超过一次
每对 相邻 整数的二进制表示 恰好一位不同 ,且
第一个 和 最后一个 整数的二进制表示 恰好一位不同
给你一个整数 n
,返回任一有效的 n 位格雷码序列 。
示例 1
输入:n = 2
输出:[0,1,3,2]
解释:
[0,1,3,2] 的二进制表示是 [00,01,11,10] 。
- 00 和 01 有一位不同
- 01 和 11 有一位不同
- 11 和 10 有一位不同
- 10 和 00 有一位不同
[0,2,3,1] 也是一个有效的格雷码序列,其二进制表示是 [00,10,11,01] 。
- 00 和 10 有一位不同
- 10 和 11 有一位不同
- 11 和 01 有一位不同
- 01 和 00 有一位不同
示例 2
输入:n = 1
输出:[0,1]
提示: 1 <= n <= 16
二、代码
代码如下:
class Solution:
def grayCode(self, n: int) -> List[int]:
length = int(math.pow(2,n))
n1_grayCode = [0,1]
if n == 1:
return n1_grayCode
result = []
#转化为2进制 ,使用 [2:] 切片操作删除前缀 "0b"
bin_nums = [bin(i)[2:] for i in n1_grayCode]
print(bin_nums)
for i in range(n-1):
Pos_nums = bin_nums.copy()
Pos_nums = ['0'+i for i in Pos_nums]
bin_nums.reverse()
Re_nums = bin_nums.copy()
Re_nums = ['1'+i for i in Re_nums]
# print(Pos_nums)
# print(Re_nums)
bin_nums = Pos_nums.copy() + Re_nums.copy()
# print(bin_nums)
print(bin_nums)
result = [int(i,2) for i in bin_nums]
print(result)
return result
三、解题思路
本题如果不知道什么是格雷编码的规律会有点难理解,在此介绍一下格雷编码的生成规律:
格雷编码数组的长度为2n,其中n
为正整数;
当n=1时,格雷编码G(1)=[0,1]
,对应的二进制为[0,1]
当n=2时,格雷编码G(2)=[0,1,3,2]
,对应的二进制为[00,01,11,10]
满足格雷编码要求。
实际上G(n)
的可以由G(n-1)
求出(n>1)
,以G(2)
为例,具体步骤如下:
① 将n-1
的格雷编码转化为2进制形式:
bin_nums = [0,1]
②然后在所有元素前面加”0“,用Pos_nums存储:
Pos_nums = [00,01]
③之后逆序n-1的格雷编码:
bin_nums = [1,0]
④然后在所有元素前面加“1”,用Re_nums存储:
Re_nums = [11,10]
⑤最后拼接上面加好了的数组组成新数组bin_nums:
bin_nums = Pos_nums + Re_nums
即bin_nums = [00,01,11,10]
⑥最后循环结束将bin_nums转化为int类型并保存在result数组中:
result = [int(i,2) for i in bin_nums]
即result = [0,1,3,2]
同理,如果要求任意n
对应的格雷编码,只需要循环上述①~⑤的操作n-1
次,最后执行⑥即可。
以上就是本题题解,算法实现方面并不难,主要是如何寻找规律。
需要注意的是,在对二进制数据进行加“0”和加“1”操作时,本题解的方法是先将其转化为字符串,然后再相加,将int类型的数值转化为2进制字符串的方法为bin()方法,该方法之间使用后会在二进制前面加上“0b”的字符,需要删除之后才方便后面的添加操作。