89. 格雷编码 Python


一、题目描述

n 位格雷码序列 是一个由 2n 个整数组成的序列,其中:

每个整数都在范围 [0, 2^n - 1] 内(含 02^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”的字符,需要删除之后才方便后面的添加操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值