格雷編碼-lc89
阿新 • • 發佈:2020-12-19
題目連結:傳送門
題目大意:
對於給定的非負整數n,返回一個長度位$2^n$序列
要求:
- 相鄰兩個數的位數僅有一位差距
- 所有數字不相同
- 第一個數字位0
解法一:(虛假的解法
class Solution { public: vector<int> grayCode(int n) { vector<int> ans; ans.push_back(0); //遍歷位數 for(int i = 0;i < n;i++){ //取前一次長度遍歷 for(int j = ans.size() - 1;j >= 0;j--){ //每次新增ans[j] ^ ( 1 << i),即令當前遍歷位數的bit為1 ans.push_back(ans[j] ^ (1 << i)); } } return ans; } }; // 0000 0001 0011 0010 0110 0111 0101 0100
上面的解法並不困難,且容易理解。
解法二
此解法我理解不深刻,有錯誤之處還請指正。
List<Integer> list = new ArrayList<>();
for(int i = 0;i < 1 << n;i++){
ans.add(i ^ i >> 1);
}
return ans;
先證明相鄰兩數只差一位
$$
x \otimes (x >> 1) ^ ((x + 1) \otimes ((x + 1) >> 1))\
= [x \otimes (x + 1)] \otimes [(x >> 1) \otimes ((x + 1) >> 1)]\
$$
因此先計算$$x \otimes (x + 1) $$,不妨計算過程為下面的形式
同理另一半的值以為向右移動一位應該為下面的形式
很明顯可以知道最終的計算結果應該為
最終我們得到到了相鄰兩個數值差這一位。
而這些證明並不能代表我們的題解是正確的,還需要證明這$1 << n$個數完全不相等
考慮這樣的事:當n == 3時,我們已經有
0 , 1, 3, 2
那麼後買你4個數如和新增的呢,此時題解中的$i == 4$那麼$ i \otimes (i >> 1)$應該保留第一位的1,並且
$$
(x + 1) \otimes ((x + 1) >> 1)\
= x \otimes ( x >> 1) \otimes (x的最低一位0)\
$$
一旦$x$跨越$x^i - 1$的時候那麼 $x \otimes (x >> 1)$一定會保證最高一位是1,更細節一點的證明我想不出來了
算證明了3/4吧