力扣题解 第17期:89. 格雷编码

89. 格雷编码

1、题干

n 位格雷码序列 是一个由 2^n 个整数组成的序列,其中:

  • 每个整数都在范围 [0, 2^n - 1] 内(含 02^n - 1
  • 第一个整数是 0
  • 一个整数在序列中出现 不超过一次
  • 每对 相邻 整数的二进制表示 恰好一位不同 ,且
  • 第一个最后一个 整数的二进制表示 恰好一位不同

给你一个整数 n ,返回任一有效的 n 位格雷码序列

示例 1:

输入: n = 2
输出: [0,1,3,2]
解释:
[0,1,3,2] 的二进制表示是 [00,01,11,10] 。
[0,2,3,1] 也是一个有效的格雷码序列,其二进制表示是 [00,10,11,01] 。

示例 2:

输入: n = 1
输出: [0,1]

提示:

  • 1 <= n <= 16

2、直接计算

直接计算的公式是: G ( n ) = n n 2 G(n) = n \oplus \dfrac{n}{2} 。其中 G ( n ) G(n) 表示第 n n 个格雷码。

3、代码

var grayCode = function(n) {
    const ret = [];
    for (let i = 0; i < 1 << n; i++) {
        ret.push((i >> 1) ^ i);
    }
    return ret;
};
复制代码

4、镜像对称构造

  • 将前2k个格雷码去除首位二进制数并分成两半后具有镜像对称性。(如下图3位格雷码)
  • n位格雷码是将n-1位格雷码作为前半部分,将n-1位格雷码倒序遍历并在其二进制数之前添1作为后半部分。(如下图3位格雷码与2位格雷码关系)

image.png

5、代码

var grayCode = function (n) {
    const arr = [0, 1];
    for (let i = 2; i <= n; i++) {
        for (let j = arr.length - 1; j > -1; j--) {
            arr.push(arr[j] | (1 << (i - 1)));
        }
    }
    return arr;
};
复制代码

6、交替构造

以3位格雷码为例:

  • n = 0 开始,按以下2步反复操作,即可得到所有格雷码
  • n 为偶数:翻转最低位得到下一个格雷码,如 000 变成 001
  • n 为奇数:把最右边的 1 左边的位翻转得到下一个格雷码,如 001 变成 011

实现略复杂,暂无代码,建议优先使用前2种方法生成


原题链接:leetcode-cn.com/problems/gr…

猜你喜欢

转载自juejin.im/post/7054479722591289374