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位格雷码后。
故此问题有两种解法
- 自顶而下(回溯),从n位格雷码求解开始,进行递归,直到碰到n=0边界条件返回。
- 自底而上(递推),从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;
}
};