89.格雷编码

·题目描述

89. 格雷编码

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

  • 每个整数都在范围 [0, 2n - 1] 内(含 02n - 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));
    }
}
相关推荐
雨中飘荡的记忆8 小时前
ElasticJob分布式调度从入门到实战
java·后端
灵感__idea10 小时前
Hello 算法:众里寻她千“百度”
前端·javascript·算法
考虑考虑16 小时前
JDK25模块导入声明
java·后端·java ee
_小马快跑_18 小时前
Java 的 8 大基本数据类型:为何是不可或缺的设计?
java
Wect20 小时前
LeetCode 130. 被围绕的区域:两种解法详解(BFS/DFS)
前端·算法·typescript
Re_zero20 小时前
线上日志被清空?这段仅10行的 IO 代码里竟然藏着3个毒瘤
java·后端
洋洋技术笔记20 小时前
Spring Boot条件注解详解
java·spring boot
NAGNIP1 天前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
程序员清风2 天前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5512 天前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java