力扣 题目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
     248

即每次新加的前一半 是旧的对应位置加上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 }
View Code

代码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 }
View Code

 

posted @ 2022-07-12 16:44  无聊的阿库娅  阅读(18)  评论(0编辑  收藏  举报