【JS每日一算法】🟨83.格雷编码(归纳法、数学公式)

365 阅读1分钟

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

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

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

提示:

  • 1 <= n <= 16

示例 1:

输入:n = 2
输出:[0,1,3,2]
解释:
[0,1,3,2] 的二进制表示是 [00,01,11,10] 。
- 0001 有一位不同
- 0111 有一位不同
- 1110 有一位不同
- 1000 有一位不同
[0,2,3,1] 也是一个有效的格雷码序列,其二进制表示是 [00,10,11,01] 。
- 0010 有一位不同
- 1011 有一位不同
- 1101 有一位不同
- 0100 有一位不同

示例 2:

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

题解:

更多JS版本题解点击链接关注该仓库👀

/**
 * @description: 归纳法    TC:O(2^n)   SC:O(n)
 * @author: JunLiangWang
 * @param {*} n  给定整数n
 * @return {*}
 */
function inductionMethod(n){
    /**
     * 该方案使用归纳法,给定以下格雷码序列:
     * 
     * n=   0     1    2     3      4
     *      0     0    0     0      0
     *            1    1     1      1
     *                11    11     11
     *                10    10     10
     *                     110    110
     *                     111    111
     *                     101    101
     *                     100    100
     *                            ...
     * 我们可以找到规律,对于格雷序列n,它的前半部分
     * 是等于n-1的格雷序列,而它的后半部分等于前半部
     * 分倒序,在最高位补1。
     * 根据该规律,我们遍历模拟该过程即可
     */
    let outArray=[0];
    for(let i=1;i<=n;i++){
        let len=outArray.length;
        for(let j=len-1;j>=0;j--){
            outArray.push(outArray[j]|(1<<(i-1)));
        }
    }
    return outArray;
}


/**
 * @description: 数学公式法  TC:O(2^n)  SC:O(n)
 * @author: JunLiangWang
 * @param {*} n 给定整数n
 * @return {*}
 */
function mathMethod(n){
    /**
     * 该方案使用数学公式,求第i位格雷码序列有以下公式:
     *  G(i)= (i>>1)^i   ^为位异或
     */
    let outArray=[];
    for(let i=0;i<Math.pow(2,n);i++)outArray.push((i>>1)^i);
    return outArray;
}

来源:力扣(LeetCode)