力扣 题目89- 格雷编码
题目
题解
离经叛道法
由于我对C++的二进制不太会用 所以我就想能不能不用二进制做
我们直接测试一下1-5结果
1->0,1
2->0,1,3,2
3->0,1,3,2,6,7,5,4
4->0,1,3,2,6,7,5,4,12,13,15,14,10,11,9,8
5->0,1,3,2,6,7,5,4,12,13,15,14,10,11,9,8,24,25,27,26,30,31,29,28,20,21,23,22,18,19,17,16
能不能找规律呢 毕竟一眼看上去就像有规律的样子
我们发现每个结果的前一半是上一个结果 那么上一半我们已经解决了 重要的还是另一半
我们发现以下规律
1->0,1 2->0,1, 3,2 3与1 3->0,1/,3,2, 6,7/,5,4 6与2 4->0,1,3,2,/6,7,5,4, 12,13,15,14,/10,11,9,8 12与4 5->0,1,3,2,6,7,5,4,/12,13,15,14,10,11,9,8, 24,25,27,26,30,31,29,28,/20,21,23,22,18,19,17,16 24 与 8
即每次新加的前一半 是旧的对应位置加上3*(2^(n-2)) 每次新加的后一半 是旧的对应位置加上2^(n-2)的倍数
所以得到代码
1 int add = 1; 2 for (int i = 1; i < n; i++) { 3 int len = result.size(); 4 int lentwo = (result.size() / 2) - 1; 5 for (int j = 0; j < len; j++) { 6 if (j <= lentwo) { 7 result.push_back(result[j] + add*3); 8 } 9 else 10 { 11 result.push_back(result[j] + add); 12 } 13 } 14 add *= 2; 15 }
二进制法
看了评论区 才知道
/** 关键是搞清楚格雷编码的生成过程, G(i) = i ^ (i/2); 如 n = 3: G(0) = 000, G(1) = 1 ^ 0 = 001 ^ 000 = 001 G(2) = 2 ^ 1 = 010 ^ 001 = 011 G(3) = 3 ^ 1 = 011 ^ 001 = 010 G(4) = 4 ^ 2 = 100 ^ 010 = 110 G(5) = 5 ^ 2 = 101 ^ 010 = 111 G(6) = 6 ^ 3 = 110 ^ 011 = 101 G(7) = 7 ^ 3 = 111 ^ 011 = 100 **/
是这样一个关系 所以可以得到代码
for(int i = 0; i < 1<<n; ++i) ret.add(i ^ i>>1);
代码
代码1
1 #include<iostream> 2 #include<vector> 3 #include <math.h> 4 using namespace std; 5 6 7 class Solution { 8 public: 9 vector<int> grayCode(int n) { 10 vector<int> result = {0,1}; 11 int add = 1; 12 for (int i = 1; i < n; i++) { 13 int len = result.size(); 14 int lentwo = (result.size() / 2) - 1; 15 for (int j = 0; j < len; j++) { 16 if (j <= lentwo) { 17 result.push_back(result[j] + add*3); 18 } 19 else 20 { 21 result.push_back(result[j] + add); 22 } 23 } 24 add *= 2; 25 } 26 return result; 27 } 28 }; 29 30 int main() { 31 Solution sol; 32 vector<int> result=sol.grayCode(5); 33 for (int i = 0; i < result.size(); i++) { 34 cout << result[i] << endl; 35 } 36 }
代码2
1 #include<iostream> 2 #include<vector> 3 #include <math.h> 4 using namespace std; 5 6 7 class Solution { 8 public: 9 vector<int> grayCode(int n) { 10 vector<int> result = {0,1}; 11 for (int i = 2; i < 1 << n; ++i) 12 result.push_back(i ^ i >> 1); 13 return result; 14 } 15 }; 16 17 int main() { 18 Solution sol; 19 vector<int> result=sol.grayCode(5); 20 for (int i = 0; i < result.size(); i++) { 21 cout << result[i] << endl; 22 } 23 }