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));
    }
}
相关推荐
mldong1 小时前
"applicant" 契约:退回发起人的闭环设计
java·架构
月华路1 小时前
G1 垃圾回收:脏卡队列、记忆集与并发精化线程机制
java·开发语言
gugucoding2 小时前
47. 【Java】Java内存模型(JMM)与可见性
java·开发语言
zww89491112 小时前
校园跑腿系统开发实战指南:从需求分析到上线部署全流程解析
java
Fluxart.ai3 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
罗西的思考3 小时前
【Agent OS / AIOS】AOHP 深度解读:当 OS 开始为 Agent 而设计
人工智能·算法·机器学习
民乐团扒谱机4 小时前
【微实验】组合优化matlab实战(马科维茨投资模型):在收益与风险之间,寻找最优的人生配比
大数据·人工智能·算法·机器学习·数学建模·matlab·组合优化
名字还没想好☜4 小时前
Java 线上内存泄漏排查实战:jmap 导堆、MAT 找 GC Roots 与四类常见泄漏
java·开发语言·jvm·内存泄漏
Nil2084 小时前
leetcode 160相交链表
算法·leetcode·链表
迷途之人不知返5 小时前
算法系列2:滑动窗口
算法