【leetcode】89. 格雷编码 (格雷码+位运算+模拟)

题目描述

格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。即使有多个不同答案,你也只需要返回其中一种。
格雷编码序列必须以 0 开头。

示例 1:

输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2
对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。
00 - 0
10 - 2
11 - 3
01 - 1

示例 2:

输入: 0
输出: [0]
解释: 我们定义格雷编码序列必须以 0 开头。
给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。
因此,当 n = 0 时,其格雷编码序列为 [0]。

题目链接:89. 格雷编码

思路:

  • 首先要明白格雷码的构造方法:已知 i i i位格雷码,只需将 i i i位格雷码镜像后,在前半部分的前面填0,在后半部分的前面添1即可得到 i + 1 i+1 i+1位格雷码。

  • 由于题目中输出的是格雷码表示的十进制数,而在最前面添0不改变十进制数,故 i + 1 i+1 i+1位格雷码的前半部分和 i i i位格雷码一致。

  • 最终的做法就是:逐步构造 0 、 1 、 2 、 ⋅ ⋅ ⋅ 、 n 0、1、2、···、n 012n位格雷码, i i i位格雷码只需将 i − 1 i-1 i1位格雷码的每个数上加 i < < 1 i<<1 i<<1(起到将第 i i i位置为1的作用)并镜像加到答案数组里即可。

  • 格雷码镜像构造方法如下表,其中二进制后为其对应十进制数:

1位格雷码 2位格雷码 3位格雷码 4位格雷码
0(0) 00(0) 000(0) 0000(0)
1(1) 01(1) 001(1) 0001(1)
11(3) 011(3) 0011 (3)
10(2) 010(2) 0010(2)
110(6) 0110(6)
111(7) 0111(7)
101 (5) 0101(5)
100(4) 0100(4)
1100(12)
1101(13)
1111(15)
1110(14)
1010(10)
1011(11)
1001(9)
1000(8)

C++代码:

class Solution {
    
    
public:
    vector<int> grayCode(int n) {
    
    
    vector<int>res(1<<n,0);   //n位格雷码有2^n个元素
    int i=0,p=0;     //i表示第i位格雷码,p表示“镜像的分界面”       
    while(i<n){
    
    
    for(int l=p,r=p+1;l>=0;l--,r++){
    
    
    res[r]=res[l]+(1<<i);  //将l处的元素前面添1放到镜像r处 
    }
    i++;          //增加“格雷码位数"
    p=(1<<i)-1;   //更新“分界面”
    }
    return res;
    }
};

猜你喜欢

转载自blog.csdn.net/IAMLSL/article/details/115268874