zoukankan      html  css  js  c++  java
  • 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异或也可以,哎我去,还真行,而且越想越觉得方便,连二进制向十进制转换都省了。

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

  • 相关阅读:
    LeetCode偶尔一题 —— 617. 合并二叉树
    《剑指offer》 —— 链表中倒数第k个节点
    《剑指offer》 —— 青蛙跳台阶问题
    《剑指offer》—— 二维数组中的查找
    《剑指offer》—— 替换空格
    《剑指offer》—— 合并两个排序的链表
    《剑指offer》—— 礼物的最大价值
    生成Nuget 源代码包来重用你的Asp.net MVC代码
    Pro ASP.Net Core MVC 6th 第四章
    Pro ASP.NET Core MVC 6th 第三章
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10603948.html
Copyright © 2011-2022 走看看