89.格雷编码

·题目描述

89. 格雷编码

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

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

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

示例 1:

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

示例 2:

复制代码
输入:n = 1
输出:[0,1]

·格雷编码的规律

格雷编码是n= 0 也就是编码数组nums = 【0】开始往上递增的。递增的规律有两个:

1.保持nums数组中前元素不变,在nums后端不断添加新元素。新元素的构成是在原始数组上逆序遍历,再在该元素的最高位添加一个1 ,在二进制中表述为

复制代码
(ground.get(i) | size)
size = nums.size()

表示对nums列表中的第 i 个元素执行按位或操作,并且按位或操作的右操作数是 size。

复制代码
假设 nums 列表当前包含 [0, 1],并且 size 是 4。

对于 nums.get(0) = 0:

nums.get(0) | size 将会生成一个新的 Gray 码。
nums.get(0) 的二进制表示是 0000,size 的二进制表示是 0100。
将它们进行按位或运算:0000 | 0100,得到结果 0100,即 4。
对于 nums.get(1) = 1:

nums.get(1) | size 将会生成另一个新的 Gray 码。
nums.get(1) 的二进制表示是 0001,size 的二进制表示是 0100。
将它们进行按位或运算:0001 | 0100,得到结果 0101,即 5。

2.原始的nums元素全部左移并且后端添上0,在十进制中表示为×2的操作;然后采用逆序,nums的元素左移并且后端添加1,添加到nums后端。

例如

n = 1 时候 , nums = 0 , 1

复制代码
将0->00, 1 -> 10,并且逆序遍历1->11,0 ->01

所以n = 2 的时候, nums =00, 01, 11, 10

同理可得 ,n = 3 的时候, nums = 000,010,110,100 , 101,111,011,001

java 复制代码
import java.util.ArrayList;
import java.util.List;

class Solution {
    List<Integer> ground = new ArrayList<>();

    public List<Integer> grayCode(int n) {
        ground.add(0);
        backtrack(n);
        return ground;
    }
    public void backtrack( int n) {
        int size = ground.size();
        if (size == (int) Math.pow(2,n)) return;
        
        //构建方法1
        for(int i = size - 1; i >= 0; i --){
            int num = (ground.get(i) | size)  ;
            ground.add(num);
        }
        backtrack(n);
        
        //构建方法2
        for(int i = size - 1; i >= 0; i --){
            int num = (ground.get(i) << 1) | 1 ;
            ground.add(num);
        }
        for(int i = 0; i < size ; i ++){
            ground.set(i , ground.get(i) * 2);
        }
        backtrack(n);
    }
}

public class Main {
    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.grayCode(3));
    }
}
相关推荐
阿俊-全栈开发1 小时前
LikeShop 单商户SaaS商城分销模块二开:佣金计算与结算逻辑实现
java·开发语言·微服务·likeshop·likeshop开源商城·likeshop多商户
Logic1014 小时前
C语言/数据结构位运算题解:异或XOR找出学习计划中的“独特学习时间“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
wuminyu4 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
小蒋学算法4 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
荆棘鸟智能4 小时前
林业遥感长势评估怎么做?从NDVI时序分析到LiDAR蓄积量回归
人工智能·算法·智慧林业
hhb_6185 小时前
AIRAGDebug:一键定位RAG链路异常
人工智能·python·算法
朝朝辞暮i6 小时前
C++ 第 6 课:switch —— 多状态选择
开发语言·c++·算法
苏打豆6 小时前
Pinocchio源码阅读——刚体运动物理量空间变换及求导
c++·线性代数·算法·矩阵·机器人
蜗牛互联网6 小时前
WSL Containers GA:本地AI容器的生命周期、网络与治理验收
java·网络·人工智能·后端
FluxArt6 小时前
GPT Image 2.5 中文提示词教程:Flux Art 可复用模板
前端·gpt·算法