题目:格雷码
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代表格雷码总共的位数,打印出所有的格雷码序列。格雷码序列必须从0开始。
Note:
1、对于给定的n值,格雷码序列不是唯一的;
2、例如,根据如上定义,[0,2,3,1]也是一个有效的格雷码序列;
3、目前,这个judge系统能够judge基于格雷码的一个实例。
转载地址:leetcode题解
思路一:
利用数学公式对从0到2^n-1的所有整数转化为格雷码。
代码:C++版:8ms
class Solution { public: vector<int> grayCode(int n) { vector<int> res; const int size = 1<<n; //2^n res.reserve(size); //vector最小容量为size大小 for (int i=0; i<size; ++i) //将0到2^n-1之间的数都转化为格雷码 res.push_back(binary_to_gray(i)); return res; } private: static int binary_to_gray(int n) { //普通数转化为格雷码 return n^(n>>1); } };简化代码版本,思路一致;
代码:C++版:4ms
class Solution { public: vector<int> grayCode(int n) { vector<int> res; for (int i=0; i<(1<<n); ++i) { res.push_back(i^(i>>1)); } return res; } };
思路二:
回溯法(递归法)实现。长度为n位的格雷码可以递归地从长度为n-1位的格雷码生成。如上图分析所示。
代码:C++版:4ms
class Solution { public: vector<int> grayCode(int n) { vector<int> res; res.reserve(1<<n); res.push_back(0); for (int i=0; i<n; i++) { const int highest_bit = 1<<i; for (int j=res.size()-1; j>=0; j--) { //要反着遍历才能对称 res.push_back(highest_bit | res[j]); } } return res; } };
转载地址:http://www.cnblogs.com/grandyang/p/4315649.html
思路三:
维基百科上还有一条格雷码的性质是直接排列,以二进制为0值的格雷码为第零项,第一项改变最右边的位元,第二项改变右起第一个为1的位元的左边位元,第三、四项方法同第一、二项,如此反复,即可排列出n个位元的格雷码。根据这条性质也可以写出代码,不过相比前面的略微复杂。
代码:C++版:4ms
class Solution { public: vector<int> grayCode(int n) { vector<int> res(1, 0); int len = 1<<n; for (int i=1; i<len; ++i) { int pre = res[i-1]; if (i%2 != 0) { res.push_back((pre & (len-2)) | ((~pre)&1)); } else { int count = 0; while ((pre&1) != 1) { ++count; pre = pre>>1; } pre = pre>>1; pre = (pre&(len-2)) | ((~pre)&1); pre = (pre<<1) | 1; res.push_back(pre<<count); } } return res; } };