zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    【mpeg2】MPEG-2官方参考代码MPEG2_reference_software
    【base】Copyright 与 Copyleft
    【base】Copyright 与 Copyleft
    【complier】如何查看ARM交叉编译的可执行程序依赖的动态库?
    【shell系列】之查看shell脚本的执行过程和makefile中调试手段
    【tools】一款强大的局部搜索工具:xsearch
    【tools】一款强大的局部搜索工具:xsearch
    【mpeg2】mpeg2编码器的开源实现:x262
    【mpeg2】mpeg2解码器开源实现:libmpeg2
    【codecs】视频显示分辨率格式分析
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14237464.html
Copyright © 2011-2022 走看看