格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
给定一个代表编码总位数的非负整数 n,打印格雷码序列。格雷码序列必须以 0 开头。
例如,给定 n = 2,返回 [0,1,3,2]
。其格雷编码是:
00 - 0 01 - 1 11 - 3 10 - 2
1 #include<math> 2 class Solution { 3 public: 4 void dfs(vector<int>& ans, int cur, int n){ 5 if(n == 0) {ans.push_back(0); return;}//只有一位格雷,特别处理 6 if(cur > n) return; 7 if(cur == 1){ 8 ans.push_back(0); 9 ans.push_back(1); 10 dfs(ans, cur+1, n); 11 }else{ 12 int len = ans.size();//循环前确定ans的长度,在循环中,ans的长度是变化的 13 for(int j = 0; j < len; j++) 14 ans.push_back(ans[len-j-1]); //把ans中的所有元素反向添加到ans后面 15 for(int j = len; j < 2*len; j++) 16 ans[j] = ans[j] + pow(2, cur-1); //在前面添加1, 相当于ans[j]+2^(cur-1); 17 dfs(ans, cur+1, n); 18 } 19 } 20 vector<int> grayCode(int n) { 21 vector<int> ans; 22 dfs(ans, 1, n); 23 return ans; 24 } 25 };
n位的格雷码可以由n-1位的格雷码获得
一位格雷码:0,1
两位格雷码:00,01;11,10
三位格雷码:000,001,011,010;110,111,101,100
四位格雷码:0000,0001,0011,0010,0110,0111,0101,0100; 1100,1101,1111,1110,1010,1011,1001,1000
通过上面的枚举可以发现,格雷码的实现其实是一个递归过程
例如三位格雷码的前四位是把两位格雷码按从左到右的顺序在每一个格雷码前面加0实现的,后面四位是把两位格雷码按照从右到左的顺序在每一位格雷码前面加一实现的,大家按照这个方法推一下格雷码,应该能理解这段话的意思。
此外在前面加0,格雷码对应的值不会改变,前面加一会让各类码的值增加2^(n-1),n为格雷码的位数
对上面的程序做了一点小改进
1 #include<math> 2 class Solution { 3 public: 4 void dfs(vector<int>& ans, int cur, int n){ 5 if(n == 0) {ans.push_back(0); return;}//只有一位格雷,特别处理 6 if(cur > n) return; 7 if(cur == 1){ 8 ans.push_back(0); 9 ans.push_back(1); 10 dfs(ans, cur+1, n); 11 }else{ 12 int len = ans.size();//循环前确定ans的长度,在循环中,ans的长度是变化的 13 for(int j = 0; j < len; j++) 14 ans.push_back(ans[len-j-1] + pow(2, cur-1)); 15 dfs(ans, cur+1, n); 16 } 17 } 18 vector<int> grayCode(int n) { 19 vector<int> ans; 20 dfs(ans, 1, n); 21 return ans; 22 } 23 };