LeeCode89格雷码
没有提前了解过格雷码的可能没有思路,一般会先找规律,但是会耗费很长时间也没有思路。
学习过格雷码的同学可能会记得一个公式,而这个题目也就是按照这个公式求解的。(数电课程,是不是想到卡诺图了?卡诺图也是按照格雷码画的,这里就不再细说。)
二进制编码
有权码 | 有权码 | 有权码 | 无权码 | 无权码 | |
---|---|---|---|---|---|
十进制 | 8421码 | 5421码 | 2421码 | 余3码 | BCD格雷码 |
0 | 0000 | 0000 | 0000 | 0011 | 0000 |
1 | 0001 | 0001 | 0001 | 0100 | 0001 |
2 | 0010 | 0010 | 0010 | 0101 | 0011 |
3 | 0011 | 0011 | 0011 | 0110 | 0010 |
4 | 0100 | 0100 | 0100 | 0111 | 0110 |
5 | 0101 | 1000 | 1011 | 1000 | 0111 |
6 | 0110 | 0110 | 1100 | 1001 | 0101 |
7 | 0111 | 0111 | 1101 | 1010 | 0100 |
8 | 1000 | 1011 | 1110 | 1011 | 1100 |
9 | 1001 | 1100 | 1111 | 1100 | 1101 |
- 有权码是每一位有自身的权重。
- 无权码则是每一位没有权重。
- 余3码则是8421码+3得来的。
- 格雷码是一种循环码,其特点是任何相邻的两个码字,仅有一位代码不同,其他位相同。
重点:
如何保证格雷码的特点?
十进制 | 8421码 | 异或 | 右移一位 | 格雷码 |
---|---|---|---|---|
0 | 000 | ^ | 000 | 000 |
1 | 001 | ^ | 000 | 001 |
2 | 010 | ^ | 001 | 011 |
3 | 011 | ^ | 001 | 010 |
4 | 100 | ^ | 010 | 110 |
5 | 101 | ^ | 010 | 111 |
6 | 110 | ^ | 011 | 101 |
7 | 111 | ^ | 011 | 100 |
可以发现,格雷码是通过8421码本身和其右移一位异或得来的。
公式想表达的意思也就是如此:
G(i) = B(i) ^ B(i+1)
其中G是格雷码,B是8421码。
贴一张百度百科的图,图的意思:
- 高位补0
- 高位与后一位异或得高位
经过上面的介绍本题也就没有难度了
代码:
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> Gray(1 << n);//1左移n位;2的n次方
for (int i = 0; i != Gray.size(); ++i) {
Gray[i] = i ^ (i >> 1);//G(i) = B(i) ^ B(i+1)
}
return Gray;
}
};