LeetCode OJ 之 Gray Code(格雷码)

题目:

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.

格雷码是一个二进制数字系统,两个连续的数字的二进制数字只有一位不同。

给定一个非负整数n,代表格雷码的二进位的个数,输出格雷码序列。格雷码序列必须以0开头。

For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:

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

Note:
For a given n, a gray code sequence is not uniquely defined.

For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.

For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.

对于给定的数字n,格雷码不是唯一的。

格雷码:http://baike.baidu.com/link?url=YnRSupt_rTOzFEM5PENs1hbds0VBu-0ay3KWZc5C5NTx4wR13-ALLLzWglja-nZ-rRlkw_FQSU9IBc0MdS0uuq 。

思路:

自然二进制码转换为格雷码:g 0 = b 0 , g i = b i ⊕ b i − 1
保留自然二进制码的最高位作为格雷码的最高位(首位),格雷码次高位为二进制码的高位与次高位异或,其余各位与次高位的求法类似。例如,将自然二进制码1001,转换为格雷码的过程是:保留最高位;然后将第1 位的1 和第2 位的0 异或,得到1,作为格雷码的第2 位;将第2 位的0 和第3 位的0 异或,得到0,作为格雷码的第3 位;将第3 位的0 和第4 位的1 异或,得到1,作为格雷码的第4 位,最终,格雷码为1101。
格雷码转换为自然二进制码:b 0 = g 0 , b i = g i ⊕ b i − 1
保留格雷码的最高位作为自然二进制码的最高位,次高位为自然二进制高位与格雷码次高位异或,其余各位与次高位的求法类似。例如,将格雷码1000 转换为自然二进制码的过程是:保留最高位1,作为自然二进制码的最高位;然后将自然二进制码的第1 位1 和格雷码的第2 位0 异或,得到1,作为自然二进制码的第2 位;将自然二进制码的第2 位1 和格雷码的第3 位0 异或,得到1,作为自然二进制码的第3 位;将自然二进制码的第3 位1 和格雷码的第4 位0 异或,得到1,作为自然二进制码的第4 位,最终,自然二进制码为1111。
格雷码有数学公式,整数 n 的格雷码是 n ( n/2)。(实际是由n的自然二进制码转换为格雷码,然后由格雷码转换为十进制数,比如上面的1001->1101)
这题要求生成 n 比特的所有格雷码。
方法 1,最简单的方法,利用数学公式,对从0 ∼ 2 ^n − 1 的所有整数,转化为格雷码。
方法 2,n 比特的格雷码,可以递归地从n − 1 比特的格雷码生成。

这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:

1位格雷码有两个码字

(n+1)位格雷码中的前2^n个码字等于n位格雷码的码字,按顺序书写,加前缀0

(n+1)位格雷码中的后2^n个码字等于n位格雷码的码字,按逆序书写,加前缀1



 代码1(公式法):

class Solution {
public:
    //整数 n 的格雷码是 n ⊕ ( n/2) 
    vector<int> grayCode(int n) 
    {
        int num = 1 << n;
        vector<int> result;
        for(int i = 0 ; i < num ; i++)
        {
            result.push_back(i ^ (i >> 1));
        }
        return result;
    }
};

代码2:

2位格雷码 3位格雷码 4位格雷码 4位自然二进制码
00
01
11
10
000
001
011
010
110
111
101
100
0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111


class Solution {
public:

    vector<int> grayCode(int n) 
    {
        vector<int> result;
        result.push_back(0);
        for (int i = 0; i < n; i++) 
        {
            const int highest_bit = 1 << i;//2^i位的前2^(i-1)位不需要改变,后2^(i-1)位为用1<<i与前2^(i-1)位的逆序取或
            for (int j = result.size() - 1; j >= 0; j--) // 要反着遍历,才能对称
            {
                result.push_back(highest_bit | result[j]);
            }
        }
        return result;
    }
};




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值