• leecode第八十九题(格雷编码)


    class Solution {
    public:
        vector<int> grayCode(int n) {
            vector<int> res;
            res.push_back(0);//毕竟0开头
            if(n==0)
                return res;
            
            vector<bool> index;//建立一个长为2^n的符号数组,目的是为了在检测过程中,判断某个数值是否已经被用过了
            index.push_back(true);
            for(int i=1;i<pow(2,n);i++)
                index.push_back(false);
            
            int ans=0;//从0开始
            while(res.size()<pow(2,n))//如果res数组还没满,就得继续找
            {
                int temp=1;
                while(index[ans^temp])//分别查看,当前值ans按第一位、第二位……反转之后的值的index数组是否为假,为假说明这个值即没被用过,又与当前值只有一位改变
                    temp=temp*2;
                res.push_back(ans^temp);//打入res
                index[ans^temp]=true;//index这个值取真
                ans=ans^temp;//当前值被赋予
            }
            
            return res;
        }
    };

     分析:

    这个题有意思,我以前还学过数电,当年也是在书上也是认真推导过格雷编码的人,现在。。。

    虽然忘了真正编码的过程,但是我看题目描述以及自己动手查看了一下,发现只要只改变一位,总会遍历全部的值,在这个基础上,我想到只改变一位瞎遍历,也不能全瞎,用一个辅助空间真假判断某个值是否已被遍历。

    重点来了,本想建立一个n位的数组模拟二进制,然后每次按二进制方式求和,然后判断,此时我一度怀疑自己是不是走歪了路。

    就在这时候,我突然想用异或,遍历当前值和所有值,然后对结果检查1的个数,如果为1,再去判断是否被用过。

    此时又陷入自闭中。

    这个时候,我想如果直接改变1位直接进行判断,是不是对当前值异或0001,0010,0100,1000这样子就可以了,是不是直接用数字1,2,4,8异或也可以,哎我去,还真行,而且越想越觉得方便,连二进制向十进制转换都省了。

    激动的我带点后悔,别把我面试想算法的运气都花光了啊。

  • 相关阅读:
    BZOJ2223: [Coci 2009]PATULJCI
    BZOJ2157: 旅游
    HDU6368
    BZOJ2006: [NOI2010]超级钢琴
    BZOJ1969: [Ahoi2005]LANE 航线规划
    BZOJ1878: [SDOI2009]HH的项链
    BZOJ1798: [Ahoi2009]Seq 维护序列seq
    BZOJ1503: [NOI2004]郁闷的出纳员
    BZOJ1370: [Baltic2003]Gang团伙
    BZOJ1342: [Baltic2007]Sound静音问题
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10603948.html
Copyright © 2020-2023  润新知