• 格雷编码-lc89


    题目链接:传送门
    题目大意:

    对于给定的非负整数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吧

  • 相关阅读:
    欢迎来怼--第二十三次Scrum会议
    作业要求 20171102 每周例行报告
    小程序中添加快递查询
    微信小程序——获取用户unionId
    nodejs开发 过程中express路由与中间件的理解
    nodejs 学习心得
    js中小知识记录
    TypeError: db.collection is not a function
    MONGODB安装教程
    CSS设置DIV背景色渐变显示--针对不同浏览器,背景渐变的兼容问问题
  • 原文地址:https://www.cnblogs.com/yvzhu/p/14158641.html
Copyright © 2020-2023  润新知