89. Gray Code

问题:

给定二进制数的位数n,从0开始,每次反转一位,最终遍历完所有位反转。按顺序加入结果res。

Example 1:
Input: n = 2
Output: [0,1,3,2]
Explanation:
00 - 0
01 - 1
11 - 3
10 - 2
[0,2,3,1] is also a valid gray code sequence.
00 - 0
10 - 2
11 - 3
01 - 1

Example 2:
Input: n = 1
Output: [0,1]
 
Constraints:
0 <= n <= 15

  

解法一:Backtracking(回溯算法)

对每一位pos,

  • 初始状态0 backtrack_1
  • 反转pos位 flip[pos]
  • pos位0->1 backtrack_2

逻辑参考图:(✅ 为一层调用)

 

代码参考:

 1 class Solution {
 2 public:
 3     void backtrack(vector<int>& res, bitset<32>& bit, int n, int pos) {
 4         if(pos==n) {
 5             res.push_back(bit.to_ullong());
 6             return;
 7         }
 8         backtrack(res, bit, n, pos+1);
 9         bit.flip(pos);
10         backtrack(res, bit, n, pos+1);
11         return;
12     }
13     vector<int> grayCode(int n) {
14         vector<int> res;
15         bitset<32> bit;
16         backtrack(res, bit, n, 0);
17         return res;
18     }
19 };

解法二:一般迭代

本题规律如下:

  • 从第0位到最高位,进行( | 1)或上1
    • 每一位操作中,对既存的res,反向进行操作。
      • (由于res中相邻的两个结果一定是只有一步操作差的,因此反向依次追加入res,也能保证相邻二者只有一步操作差)
      • (至于为什么反向,为了保证:层与层之间的变换只有一步差<当前位追加 1 >)

flip[0]     res: [0000]->[0001]

                   {0000, 0001}

flip[1]      res:对既存res从后往前:[0001]->[0011]     [0000]->[0010]

                   {0000, 0001, 0011, 0010}

flip[2]     res: 对既存res从后往前:[0010]->[0110]     [0011]->[0111]     [0001]->[0101]     [0000]->[0100]

                   {0000, 0001, 0011, 0010, 0110, 0111, 0101, 0100}

flip[3]      res:对既存res从后往前:[0100]->[1100]     [0101]->[1101]     [0111]->[1111]     [0110]->[1110]     [0010]->[1010]     [0011]->[1011]     [0001]->[1001]     [0000]->[1000] 

                   {0000, 0001, 0011, 0010, 0110, 0111, 0101, 0100, 1100, 1101, 1111, 1110, 1010, 1011, 1001, 1000}

代码参考:

 1 class Solution {
 2 public:
 3     vector<int> grayCode(int n) {
 4         vector<int> res = {0};
 5         for(int pos = 0; pos < n; pos++) {
 6             int size = res.size();
 7             for(int flip = size-1; flip >=0; flip--) {
 8                 res.push_back(res[flip] | 1<<pos);
 9             }
10         }
11         return res;
12     }
13 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14237464.html