[LeetCode]89.Gray Code

简介:

【题目】

The gray code is a binary numeral system where two successive values differ in only one bit.

Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.

For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:

00 - 0
01 - 1
11 - 3
10 - 2

Note:
For a given n, a gray code sequence is not uniquely defined.

For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.

For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.

【题意】

格雷码是一个二进制数字集合,相邻两数间只有一个位元改变。

给定一个非负整数n代表的比特位的总数,打印格雷码序列。格雷码序列必须从0开始。 

例如,给定n=2,返回[0,1,3,2]。它的格雷码序列为:

00 - 0
01 - 1
11 - 3
10 - 2
注意

对于给定的n,格雷码序列不是唯一地。

例如,按上述定义[0,2,3,1]也是一个有效的格雷码序列。

现在,判定系统只能够判断基于格雷码序列的一个实例。我们对此深感抱歉。

【分析】

思路1:

格雷码 (Gray Code) 的定义请参考 wikipedia http://en.wikipedia.org/wiki/Gray_code。

  • 自然二进制码转换为格雷码:  

保留自然二进制码的最高位作为格雷码的最高位,格雷码次高位为二进制码的高位与次高位异或,其余各位与次高位的求法类似。

例如,将自然二进制码 1001,转换为格雷码的过程是:

保留最高位;然后将第 1 位的 1 和第 2 位的 0 异或,得到 1,作为格雷码的第 2 位;将第 2 位的 0 和第 3 位的 0 异或,得到 0,

作为格雷码的第 3 位;将第 3 位的 0 和第 4 位的 1 异或,得到 1,作为格雷码的第 4 位,最终,格雷码为 1101。

  • 格雷码转换为自然二进制码:

保留格雷码的最高位作为自然二进制码的最高位,次高位为自然二进制高位与格雷码次高位异或,其余各位与次高位的求法类似。

例如,将格雷码 1000 转换为自然二进制码的过程是:

保留最高位 1,作为自然二进制码的最高位;然后将自然二进制码的第 1 位 1 和格雷码的第 2 位 0 异或,得到1,

作为自然二进制码的第 2 位;将自然二进制码的第 2 位 1 和格雷码的第 3 位 0 异或,得到 1,作为自然二进制码的第 3 位;

将自然二进制码的第 3 位 1 和格雷码的第 4 位 0 异或,得到 1,作为自然二进制码的第 4 位,最终,自然二进制码为 1111

  •   格雷码有数学公式,整数 n 的格雷码是

这题要求生成 n 比特的所有格雷码。最简单的方法,利用数学公式,对从 0~ 2^n - 1的所有整数,转化为格雷码

思路2:

n 比特的格雷码,可以递归地从 n  - 1 比特的格雷码生成。

n位元的格雷码可以从n-1位元的格雷码以上下镜射后加上新位元的方式快速的得到,如右图所示一般。

红色的最高位加一即保持不变。

蓝色的最高位加一;n = 1时原格雷码十进制加1 ; n = 2时 加2 ; n = 3时 加 4 ;n= 4时 加 8............


【代码1】

/*********************************
*   日期:2014-01-23
*   作者:SJF0115
*   题号: Gray Code
*   来源:http://oj.leetcode.com/problems/gray-code/
*   结果:AC
*   来源:LeetCode
*   总结:
**********************************/
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

class Solution {
public:
    //数学公式,时间复杂度 O(2^n),空间复杂度 O(1)
    vector<int> grayCode(int n) {
        int count = 1 << n;
        vector<int> code;
        for(int i = 0;i < count;i++){
            code.push_back(binaryToGrayCode(i));
        }
        return code;
    }
private:
    int binaryToGrayCode(int n){
        return n ^ (n >> 1);
    }
};
int main() {
    Solution solution;
    vector<int> result;
    result = solution.grayCode(3);
    int n = result.size();
    for(int i = 0;i < n;i++){
        printf("%d ",result[i]);
    }
    printf("\n");
    return 0;
}





【代码2】

/*********************************
*   日期:2014-01-23
*   作者:SJF0115
*   题号: Gray Code
*   来源:http://oj.leetcode.com/problems/gray-code/
*   结果:AC
*   来源:LeetCode
*   总结:
**********************************/
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

class Solution {
public:
    //镜射排列
    vector<int> grayCode(int n) {
        int i,j,count,c;
        vector<int> code;
        //初始为0位
        code.push_back(0);
        for(i = 0;i < n;i++){
            count = code.size();
            c = 1 << i;
            //添加镜面反射的那一部分(最高位加1)
            //要反着遍历才能对称
            for(j = count - 1;j >= 0;j--){
                code.push_back(code[j] + c);
            }
        }
        return code;
    }
};
int main() {
    Solution solution;
    vector<int> result;
    result = solution.grayCode(3);
    int n = result.size();
    for(int i = 0;i < n;i++){
        printf("%d ",result[i]);
    }
    printf("\n");
    return 0;
}





格雷码转二进制数

二进制码第n位 = 二进制码第(n+1)位+格雷码第n位。因为二进制码和格雷码皆有相同位数,所以二进制码可从最高位的左边位元取0,以进行计算。(注:遇到1+1时结果视为0)
例如: 格雷码0111,为4位数,所以其所转为之二进制码也必为4位数,因此可取转成之二进制码第五位为0,即0 b3 b2 b1 b0。
0+0=0,所以b3=0
0+1=1,所以b2=1
1+1取0,所以b1=0
0+1取1,所以b0=1
因此所转换为之二进制码为0101

目录
相关文章
|
数据安全/隐私保护 C++ Python
LeetCode 804. Unique Morse Code Words
LeetCode 804. Unique Morse Code Words
129 0
Leetcode-Easy 804. Unique Morse Code Words
Leetcode-Easy 804. Unique Morse Code Words
139 0
Leetcode-Easy 804. Unique Morse Code Words
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
194 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
144 6
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
314 2
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
208 3
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
288 1
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
268 7

热门文章

最新文章

下一篇
日志分析软件