LeetCode 刷题记录 89. Gray Code

本文详细介绍了格雷码的两种生成方法:公式法和动态规划法。公式法通过二进制右移并异或得到格雷码,动态规划法则利用已知n-1位格雷码生成n位格雷码,提供了C++、Java和Python实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
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].
解法1:
公式法:
格雷码和对应的二进制有相应的转换公式:二进制向右移一位然后再与自己异或就得到了对应的格雷码

 二进制  右移一位    异或    格雷码 十进制数
  00      00    00^00=00    00     0
  01      00    00^01=01    01     1
  10      01    01^10=11    11     3
  11      01    01^11=10    10     2

c++:

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> res;
        int len = pow(2,n);
        for(int i = 0; i < len; i++){
            res.push_back((i >> 1) ^ i);
        }
        return res;
    }
};

java:

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer>  res = new ArrayList<Integer>();
        int len = (int)Math.pow(2,n);
        for(int i = 0; i < len; i++){
            res.add((i >> 1) ^ i);
        }
        return res;
    }
}

python:

class Solution(object):
    def grayCode(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        res = []
        for i in xrange(2**n):
		    res.append((i>>1) ^ i)
        return res

解法2:
动态规划法
假设我们知道了n-1的格雷码,我们如何得到n的格雷码,n位的格雷码比n-1的格雷码多一位,这一位只有0和1两种选择
很简单的策略就是在首位加上1和2,如下图中间所示,但是我们发现不满足格雷码的定义,所以后面的要倒序排列,与上边的成镜像对称
代码的策略:
首先我们要给出n=0的初始情况,即0
然后循环n次,i从0到n-1,每次在前面加0相当于没有变化,加1相当于加上2i,注意加1的要倒序排列

 n=1   n =2(不正确)  n=2
  0    00     00
  1    01     01
       10     11
       11     10

c++:

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> res{0};
        for(int i = 0; i < n; i++){
            int add = 1 << i;
            int len = res.size();
            for(int j = len-1; j >= 0; j--){
                res.push_back(res[j]+add);
            }
        }
        return res;
    }
};

java:

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

python:

class Solution(object):
    def grayCode(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        res = [0]
        for i in xrange(n):
            add = 1 << i;
            size = len(res)
            for j in xrange (size-1,-1,-1):
                res.append(res[j] + add)
            
        
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值