LeetCode --- 89. Gray Code

来源:互联网 发布:java怎么分割字符串 编辑:程序博客网 时间:2024/05/16 13:44

题目如下:

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.
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位格雷码
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。格雷码有多种编码形式。

直接排列
以二进制为0值的格雷码为第零项,第一项改变最右边的位元,第二项改变右起第一个为1的位元的左边位元,第三、四项方法同第一、二项,如此反复,即可排列出n个位元的格雷码。

镜射排列
n位元的格雷码可以从n-1位元的格雷码以上下镜射后加上新位元的方式快速的得到。这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:
1位格雷码有两个码字

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

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


二进制数转格雷码
(假设以二进制为0的值做为格雷码的0)
G:格雷码 B:二进制码

G(N) = (B(n)/2) XOR B(n)


格雷码转二进制数
二进制码第n位 = 二进制码第(n+1)位+格雷码第n位。因为二进制码和格雷码皆有相同位数,所以二进制码可从最高位的左边位元取0,以进行计算。(注:遇到1+1时结果视为0)
例如: 格雷码0111,为4位数,所以其所转为之二进制码也必为4位数,因此可取转成之二进制码第五位为0,即0 b3 b2 b1 b0。
0+0=0,所以b3=0
0+1=1,所以b2=1
1+1取0,所以b1=0
0+1取1,所以b0=1
因此所转换为之二进制码为0101。
参考自维基百科。
解法一  镜像法
规律如下图,列出了n=1,n=2,n=3时的情况。

这里写图片描述
根据这个规律如果已知n=k的情况,那么n=k+1的结果包括对n=k的结果左边补零,即保存不变,然后逆序遍历n=k的结果左边补1即可。 
runtime:4ms
class Solution {public:    vector<int> grayCode(int n) {        vector<int> result(1);        for(int i=0;i<n;i++)        {                for(int j=result.size()-1;j>=0;j--)                {                   result.push_back((1<<i)+result[j]);                }        }        return result;    }};

解法二  位运算

解法二就涉及到gray code的数学知识了,要是知道这个数学知识,可以在几分钟之内就解出这道题。 
格雷码可以由对应的十进制数求出:grayCode=i^i>>1 
runtime:4ms

class Solution {public:     vector<int> grayCode(int n) {         vector<int> result;         for(int i=0;i<1<<n;i++)         {             result.push_back(i^i>>1);         }         return result;     }};

参考资料:http://blog.csdn.net/makuiyu/article/details/44926463

                 http://blog.csdn.net/u012501459/article/details/46790683

0 0
原创粉丝点击