微软面试题: LeetCode 89. 格雷编码 middle 出现次数:2
题目描述:
89. 格雷编码 难度 中等
动态规划:
按照动态规划或者说递归的思路去想,也就是解决了小问题,怎么解决大问题。
我们假设我们有了 n = 2 的解,然后考虑怎么得到 n = 3 的解。
n = 2 的解
00 - 0
10 - 2
11 - 3
01 - 1
如果再增加一位,无非是在最高位增加 0 或者 1,考虑先增加 0。
n = 3 的解,最高位是 0
000 - 0
010 - 2
011 - 3
001 - 1
由于加的是 0,其实数值并没有变化,依然符合格雷编码的规则。
再考虑增加 1,在 n = 2 的解基础上在最高位把 1 丢过去?
n = 3 的解,在n = 2 的解 最高位加 0 得到
000 - 0
010 - 2
011 - 3
001 - 1
n = 3 的解,在n = 2 的解最高位加 1 得到 --------新增
100 - 4
110 - 6
111 - 7
101 - 5
第 4 行 001 和新增的第 5 行 100,有 3 个 bit 位不同了,不符合格雷编码规则。
可以在加 0 之后 ,改变一下 加 1 的顺序,第五行 将第四行的最高位从 0 变成 1,
其余不变,第六行 将第 3行的最高位从 0 变为 1,其余不变。依次类推。
现在成功根据 n = 2 的解 推出 n = 3 的解了,问题解决。
1 class Solution { 2 public: 3 vector<int> grayCode(int n) 4 { 5 vector<int> res; 6 res.push_back(0); 7 if(n == 0) return res; 8 res.push_back(1); 9 if(n == 1) return res; 10 for(int i = 2;i <= n;++i) 11 { 12 int tmp_len = res.size(); 13 for(int j = tmp_len - 1; j >= 0; --j) 14 { 15 int add = 1 << i-1;//用移位操作更快 16 // int add = power(2,i-1); 17 res.push_back(res[j] + add); 18 } 19 } 20 return res; 21 } 22 };