LeetCode 89 _ Gray Code 格雷码

Description:

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.

Example 1:

Input: 2
Output: [0,1,3,2]
Explanation:
00 - 0
01 - 1
11 - 3
10 - 2

For a given n, a gray code sequence may not be uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence.

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

Example 2:

Input: 0
Output: [0]
Explanation: We define the gray code sequence to begin with 0.
             A gray code sequence of n has size = 2n, which for n = 0 the size is 20 = 1.
             Therefore, for n = 0 the gray code sequence is [0].

 

 

Solution:

这道题的要求是让我们输出n位格雷码对应的二进制的十进制值

 

一看这道题描述就觉得很头疼,看了半天没看懂,一搜才知道是格雷码。格雷码似乎是机组还是什么的学过,不过早就忘了= =

格雷码据说是为了通信时避免出错而产生的,在每次+1时只变化一位。举个栗子,普通二进制在3变为4时,由011变成了100,这样需要同时将三个数都进行改变。但是在实际电路中“同时变化”是难以达到的,因此改进创造了格雷码,创造过程是这样的:

· 产生0

· 将字符串与1采取异或操作,得到1,即获得了1位格雷码的所有情况(0,1)

· 将生成的两数(二进制00,01)逆序与2(二进制10)采取异或操作,得到[3,2](二进制11,10),即获得了2位格雷码的所有情况(0,1,3,2)

· 将生成的四数(二进制000,001,011,010)逆序与4(二进制100)采取异或操作,得到[6,7,5,4](二进制110,111,101,100),即获得了2位格雷码的所有情况(0,1,3,2,6,7,5,4)

· 以此类推,产生n位格雷码

按照这一思路,既可生成n为格雷码啦~

 

顺便贴一下我开始想岔了的思路,本来想的是生成2进制再转成格雷码,实际上想复杂了,不过这个二进制转格雷码的思想获取也有可能有用?也贴这里了:

具体怎么产生的呢,还是举个栗子吧,我们产生在题目条件下输入为2时的结果:

首先产生所有的二进制,从右向左编号0~n-1,如果第i位于第i+1位相同,则对应的格雷码第i位为0,若不同,则为1(即为异或操作);若为首位则在其前方补零,再进行异或操作。

按这样的操作,就产生了格雷码。原题的要求则为输出格雷码对应的十进制,即[0,1,3,2],具体过程如下:

0 -> 00 -> 第0位与第1位为0,则第0位格雷码为0;第1位与补的0均为0,则第1位为0 -> 00 -> 0

1 -> 01 -> 第0位为1,第1位为0,则第0位格雷码为,1;第1位与补的0均为0,则第1位为0 -> 01 -> 1

2 -> 10 -> 第0位为0,第1位为1,则第0位格雷码为1;第1位为1,补的0为0,则第1位为1 -> 11 -> 3

3 -> 11 -> 第0位与第1位为1,则第0位格雷码为0;第1位为1,补的0为0,则第1位为1 -> 10 -> 2

 

按照这个思路就可以解题啦,实际上的过程就是(产生2进制数)->(按照格雷码规则将2进制数转化成格雷码)-> (将格雷码以10进制的形式输出)。

 

 

Code:

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<>();
        
        res.add(0);
        for (int i = 0; i < n; i++){
            int size = res.size();
            for (int j = size-1; j >= 0; j--){
                res.add(res.get(j) | 1 << i);
            }
        }
        return res;
    }
}

  

 

提交情况:

Runtime:  0 ms, faster than 100.00% of Java online submissions for Gray Code.
Memory Usage:  33.1 MB, less than 100.00% of Java online submissions forGray Code.

转载于:https://www.cnblogs.com/zingg7/p/10706847.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值