LeetCode :: Gray Code[正确解答,真正考察点剖析]
2014-03-30 21:25
537 查看
这道题目,一般google之会发现很多答案都很简短,代码也就几行,但是你能写到这个代码的前提是,你知道什么叫做格雷码,并且格雷码和二进制码之间的转换公式。题目如下:
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
gray code sequence is:
Note:
For a given n, a gray code sequence is not uniquely defined.
For example,
to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
可是我觉得这道题根本就不是一道考察你知识点是否全面的题目。先附上一般流行的解题代码:
这道题的解题前提是你知道这个知识点:
二进制码->格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0);(对应以上代码的for循环里的循环体)。
格雷码->二进制码(解码):从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。
但是,你面试的时候不知道这个知识点就不能做了么?不是的,其实题目里面完全已经涵盖了解题需要的信息,红字部分已经告诉我们这个格雷码的特点,并且当n == 2的时候,顺序应该是0 1 3 2,那么n == 3的时候呢? 应该可以推出是0 1 3 2 6 7 5 4,这里之间的变化规律是后一个数仅由前一个数改变一位得来,而且是从低位开始检索,如果该位改变了会变成新的数则采用这个改变,否则前进一位,继续判断。e.g:
010 ,.从低位开始改变,变为011,发现和011(十进制的3)之前是出现过的,所以该改变不采用,前进一位,变为000,发现000也出现过,仍然不采用,再推进一位,变为110,之前未出现,采用!其实就是这么一个由前一个数推出后一个的递推过程。代码实现如下:(遗憾的是时间复杂度是O(N * 2 ^ N),不过可以AC)
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.
可是我觉得这道题根本就不是一道考察你知识点是否全面的题目。先附上一般流行的解题代码:
class Solution { public: vector<int> grayCode(int n) { // Start typing your C/C++ solution below // DO NOT write int main() function vector<int> result; int nSize = 1 << n; for (int i = 0; i < nSize; ++i) { result.push_back((i>>1)^i); } return result; } };
这道题的解题前提是你知道这个知识点:
二进制码->格雷码(编码):从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变(相当于左边是0);(对应以上代码的for循环里的循环体)。
格雷码->二进制码(解码):从左边第二位起,将每位与左边一位解码后的值异或,作为该位解码后的值(最左边一位依然不变)。
但是,你面试的时候不知道这个知识点就不能做了么?不是的,其实题目里面完全已经涵盖了解题需要的信息,红字部分已经告诉我们这个格雷码的特点,并且当n == 2的时候,顺序应该是0 1 3 2,那么n == 3的时候呢? 应该可以推出是0 1 3 2 6 7 5 4,这里之间的变化规律是后一个数仅由前一个数改变一位得来,而且是从低位开始检索,如果该位改变了会变成新的数则采用这个改变,否则前进一位,继续判断。e.g:
010 ,.从低位开始改变,变为011,发现和011(十进制的3)之前是出现过的,所以该改变不采用,前进一位,变为000,发现000也出现过,仍然不采用,再推进一位,变为110,之前未出现,采用!其实就是这么一个由前一个数推出后一个的递推过程。代码实现如下:(遗憾的是时间复杂度是O(N * 2 ^ N),不过可以AC)
class Solution { public: vector<int> grayCode(int n) { int _n = 1 << n; vector<bool> isOut(_n,false); vector<int> out; int number = 0, _number; isOut[0] = true; out.push_back(0); for (int i = 1; i < _n; i++){ int flag = 1; _number = number ^ flag; while(isOut[_number] == true){ flag = flag << 1; _number = number ^ flag; } out.push_back(_number); isOut[_number] = true; number = _number; } return out; } };
相关文章推荐
- 正则表达式和通配
- 监理:知识产权
- samba服务之samba-swat后台管理
- jQuery学习笔记(4)
- Pig入门操作
- GPGPU OpenCL/CUDA 高性能编程的10大注意事项
- Monkey测试
- html注册表单与服务器
- 杨氏三角查找元素
- 一步一步学习openfire+spark(1)
- Apache参数的优化(转)
- Subclassing UITableViewCell(15)
- mongoDB的MapReduce简介
- Linux系统编程---IO操作
- [Visual Studio]透过Visual Studio 2012的选择性贴上将XML与JSON直接转成对应的类别
- C++考完啦~~~~~~
- DB2利用表空间备份重建数据库
- C++考完啦~~~~~~
- ECLIPSE 使用
- 运行命令集合