[16腾讯在线笔试题1]-GrayCode

在一组树的编码中,若任意两个相邻的代码只有一位二进制不同,则称这种编码为格雷码(GrayCode)。

请编写一个函数,使用递归的方法生成N位的格雷码并且保证这个函数的健壮性。


看到题目开始确实没有思路,不妨我们先画一下格雷码树结构。3位格雷码。


                       

                  0          1

              0    1      1    0

           0  1 1  0  0 1  1  0

我们可以发现这样的规律,最高节点0和1对应的子树是对称的。

也就是说

 f(n+1) = ‘0’ + f(n)  (最高位为0时第n位格雷码) 

 f(n+1) = '1' + f '(n)   (最高位为1时 f'(n)对应第n位格雷码的对称解)

规律发现了,但是用递归求解的对称感觉不容易下手。

我们要找出更容易完成递归的规律。


观察树,当前面m个点1的个数为奇数时,我们后一个解,我们加上左子树1,右子树0。如果是偶数,加上左子树0,右子树1。


按照这个规律写出代码。

#include<iostream>
#include <vector>
using namespace std;

void GrayCode(int n,vector<int>temp,vector<vector<int>>&ret,int numof1)
{
    if(n == 0) //终止条件
    {
        ret.push_back(temp);
        return;
    }
    if(numof1%2==0) //偶数个1
    {
        temp.push_back(0);//先放0
        GrayCode(n-1,temp,ret,numof1);
        temp.pop_back();//注意pop出0节点
        temp.push_back(1); 
        GrayCode(n-1,temp,ret,numof1+1);//1的个数加1
    }
    else if(numof1%2==1) //奇数个1
    {
        temp.push_back(1);//先放1
        GrayCode(n-1,temp,ret,numof1+1);
        temp.pop_back();
        temp.push_back(0);//后放0
        GrayCode(n-1,temp,ret,numof1);
    }
    
    
}

测试代码

int main(){
    vector<int> temp;//中间量
    vector<vector<int> > ret;//解
    int n = 8; //n位格雷码
    GrayCode(n,temp,ret,0);
    for(int i=0;i<ret.size();++i)
    {
        cout<<endl;
        for(int j=0;j<ret[0].size();++j)
        {
            cout<<ret[i][j];
        }
    }
}


你可能感兴趣的:(递归,腾讯)