zoukankan      html  css  js  c++  java
  • Gray Code -- LeetCode

    原标题链接: http://oj.leetcode.com/problems/gray-code/ 
    这道题要求求出n位的格雷码相应的二进制数,主要在于找到一种格雷码的递增方法(格雷码并非唯一的,能够有多种)。
    我们来看看有了n-1位的格雷码怎样得到n位的格雷码呢?事实上方法比較简单。首先在n-1位的格雷码前面都加入0作为前2^(n-1)个格雷码,它们一定是合法的由于除了第一位(都是0)其余位都跟n-1的格雷码一致,所以两两之间仅仅相差一位。满足要求。

    接下来看看怎样接上剩下的2^(n-1)个。我们把n-1位的格雷码倒序排列。然后在每一个前面加入1。然后接到上述的前2^(n-1)个就能够了。首先由于是倒序过来,所以中间两个元素除去第一位其它都是一样的(由于原来最后一个,如今倒序过来就是第一个),而他们第一位各自是0和1,满足格雷码的要求。而剩下的元素由于我们是n-1位的格雷码倒序排列,所以两两都是满足要求的,加上前面都一样的位1。仍然满足条件。最后看看这些数字是不是都不一样。前半部分和后半部分肯定不会一样,而由于前半部分都是0开头,后半部分都是1打头,所以互相之间也不会有反复,能够看出覆盖了全部数字,并且依次下来均满足条件。


    如此我们提出了格雷码的递推方法,我们仅仅须要做一次位数的循环,每次依据上面结果构造当前位数的结果就可以。算法复杂度是O(2+2^2+...+2^n-1)=O(2^n)。所以是指数量级的,由于是结果数量无法避免。

    空间复杂度则是结果的大小,也是O(2^n)。

    代码例如以下:

    public ArrayList<Integer> grayCode(int n) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if(n<0)
            return res;
        if(n==0)
        {
            res.add(0);
            return res;
        }
        res.add(0);
        res.add(1);
        for(int i=2;i<=n;i++)
        {
            int size = res.size();
            for(int j=size-1;j>=0;j--)
            {
                res.add(res.get(j)+(1<<(i-1)));
            }
        }
        return res;
    }
    能够看出上面代码并不须要处理前半部分,由于要求的是二进制数相应的整数,所以在前面加0等于原来的数字,所曾经面数字仅仅须要保持原来就可以,后面进行倒序然后对最高位赋1就可以。感觉更接近于一道寻找规律的题目。实现上用到一点位运算会比較简单,只是位运算是这道间的分题研究,关于位运算的访谈或专题,需要熟悉哈萨克斯坦。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    PAT (Advanced Level) Practice 1097 Deduplication on a Linked List (25分) (静态链表+测试实例)
    PAT (Advanced Level) Practice 1096 Consecutive Factors (20分)
    POJ
    LightOJ
    LibreOJ
    SGU 223 国王 状压DP
    HDU
    CodeForces
    【模板】 拉格朗日插值
    模板 求二次剩余
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4757135.html
Copyright © 2011-2022 走看看