Leetcode 89:格雷编码

Leetcode链接 : https://leetcode-cn.com/problems/gray-code/

问题描述:

格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。格雷编码序列必须以 0 开头。

格雷码特点:

  • 位数为n时,格雷码的个数为 2^n(n>1) ,且要求格雷码从零开始。
  • 格雷码在组成时遵循镜像关系。在构成n位格雷码时,需要已知n-1位格雷码的序列,且当n>0时,n位格雷码的长度为n-1格雷码的两倍。对镜像关系解释如下图所示,当n=2时,格雷码个数为4,从中间分开,格雷码后n-1位关于中心对称。

解题思路

由上可知,解决格雷码问题的两个关键点:(1)边界条件:n=0时,res=[] . (2)从n-1位格雷码到n位格雷码的递推函数:原有n-1位格雷码不变,然后对原n-1位格雷码逆序遍历,并对每个数执行g[i]+=( 1<<(n-1) ),append到原n-1位格雷码后。
故此问题有两种解法

  1. 自顶而下(回溯),从n位格雷码求解开始,进行递归,直到碰到n=0边界条件返回。
  2. 自底而上(递推),从n=0,开始逐步都求解n=1,n=2...n=n,直到得到n位格雷码。

下面给基于递归的C++实现

class Solution {
public:
    vector<int> grayCode(int n) {
        if(n==0){
            vector<int> vec;
            vec.push_back(0);
            return vec;
        }
        vector<int> pre=grayCode(n-1);
        int add_item=1<<(n-1);
        int size=pre.size();
        for(int i=size-1;i>=0;i--){
            pre.push_back(add_item+pre[i]);
        }
        return pre;
    }
    
};
posted @ 2019-09-18 22:04  fancy_li  阅读(232)  评论(0编辑  收藏  举报