Gray Code

The gray code is a binary numeral system where two successive values differ in only one bit.

Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.

For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:

00 - 0
01 - 1
11 - 3
10 - 2

Note:
For a given n, a gray code sequence is not uniquely defined.

For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.

For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.


Solution:

如果不加深入思考,可能就直接搜索了,也就是每次都试着去改变最后一个已经构造好的“01串”中的某一位,如果还没有被加入到ans集合就加进去并且将它作为最后一个已经构造好的“01串”更新。稍微需要注意的就是从已知状态只要找到一个新的合法串就需要更新查找标准了(也就是要根据刚找到的串作为标准继续搜索了)。

代码如下:

 class Solution:
# @param {integer} n
# @return {integer[]}
def grayCode(self, n):
self.n = 1 << n
self.hasGet = [False] * self.n
self.hasGet[0] = True
self.len = 1
self.str = [0] * n
self.ans = [0]
self.search(n)
return self.ans def search(self, n):
while self.len < self.n:
for i in range(n):
self.reverse(i)
num = self.getNum(n)
if self.hasGet[num]:
self.reverse(i)
else:
self.ans.append(num)
self.hasGet[num] = True
self.len += 1
break def reverse(self, i):
if self.str[i] == 1:
self.str[i] = 0
else:
self.str[i] = 1 def getNum(self, n):
ans, prod = 0, 1
for i in range(n):
if self.str[i] == 1:
ans += prod
prod *= 2
return ans

可以通过,但是效率不够高。

问题的关键在于我们只是盲目地去查找和试探对于当前最后一个“01串”改变一位后行不行,具体表现在代码中,是从最低位到最高位的顺序来试探的(for i in range(n))。

但这样的顺序在这个搜索中完全是随意无序不加思考的,也是这里导致了代码效率不够高。

我们有没有一种策略,使得我每次都可以完全确定去改变已经存在于 ans 中的某个“01串”中某一个位,使得它一定就是我们要找的合法串呢?

也就说,我们可不可以不用试探,直接去找我们需要的串,然后改变我们指定的某一位后,就是我们马上要找的新的“01串”。

得益于二进制的优美与简洁,这样的策略并不难找。

考虑这样的一种状态,我们已经找到了所有  n位及比n少的位 的二进制数,现在我们如何合法的去扩展第 n+1 位?

这个时候,整个 ans 集合已经有 2^n 个数了,此时我无论再改变 1 - n 的任何一位都不再是合法的我们要找的新串(因为所有 n 位 二进制都已经被找到了,再改变 1-n 位中任何一位都不再产生“新解”)。

所以第 2^n+1 个数一定是在第 2^n 个数基础上,将第 n+1 位置 1 后得到的新的 n+1 位 二进制串,也就是此时需要找的“新解”。

那么我们如何由这个“新解”推出更多呢?

依旧把焦点放在我们已经找到过的“旧解”上。

第 2^n 个数 与 第 2^n+1 个数是第 n+1 位不同,而 第2^n个数 与 第2^n-1个数一定是在 1..n 位中 有且仅有 一位 不相同。由此可以得知,第2^n+1个数 与 第2^n-1个数 有两位不同,即 第 n+1 位变成了 1,然后 1..n 位中有且仅有某一位不相同。此时我们如何再得到新解?

很简单,把 第 2^n-1 个数 的第 n+1 位变成 1 就是我们当前已经找到了 2^n+1 个数后的 “新解”,也就是 第 2^n+2 个数!

同理,借助“相邻数有且仅有一位不同”这样的规则,我们可以“从后向前”一路扫描我们已经得到的 2^n 个数,每次都仅仅把它们的 第 n+1 位置1,然后放心大胆的加入到 ans 集合的最后面,便是我们需要得到的 “新解” 了。这样我们利用已经得到的 “牢固的二进制翻转一位的链条” 再一次反向构造回去,打个来回,新的相同数目的解便出来了!

(对于 n+1 位二进制数,第n+1为0的某个数一定可以找到另外一个第n+1位为1的另外某个数,使得它们的 1..n 位是完全相同的。第n+1为0的数的总数也刚好与第n+1为1的数的总数是一样的,所以每次对于当前最高位的循环也都将 ans 集的规模扩大一倍)

代码如下:

 class Solution:
# @param {integer} n
# @return {integer[]}
def grayCode(self, n):
ans = [0]
for i in range(n):
p = 1 << i
s = len(ans)
while s > 0:
s -= 1
v = p | ans[s]
ans.append(v)
return ans

【LeetCode】Gray Code的更多相关文章

  1. 【leetcode】Gray Code (middle)

    The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...

  2. 【题解】【排列组合】【回溯】【Leetcode】Gray Code

    The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...

  3. 【Leetcode】【Medium】Gray Code

    The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...

  4. 【LeetCode】回溯法 backtracking(共39题)

    [10]Regular Expression Matching [17]Letter Combinations of a Phone Number [22]Generate Parentheses ( ...

  5. 【LeetCode】392. Is Subsequence 解题报告(Python)

    [LeetCode]392. Is Subsequence 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/is-subseq ...

  6. 【LeetCode】722. Remove Comments 解题报告(Python)

    [LeetCode]722. Remove Comments 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/remove-c ...

  7. 【LeetCode】831. Masking Personal Information 解题报告(Python)

    [LeetCode]831. Masking Personal Information 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzh ...

  8. 【LeetCode】Minimum Depth of Binary Tree 二叉树的最小深度 java

    [LeetCode]Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum dept ...

  9. 【Leetcode】Pascal&#39;s Triangle II

    Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3 ...

随机推荐

  1. 利用windbg 分析IIS 的线程池w3wp程序多线程挂起问题

    前几天有个朋友发个了在windows server 2008跑的IIS 跑的程序w3wp程序dmp,要我帮忙分析为何线程都挂起不运行 经过查阅资料用windbg可以调试可以输出线程的调用堆栈,但是准备 ...

  2. SpringMVC Model

    处理模型数据 ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据. @ModelAttribute:方法入参标注了该注解后,入参对象会放到数据模 ...

  3. 工作需求----表单select多选交互

    由于工作需求接触select框多选的情况,以下是我分享的代码,主要是进入页面默认选中.支持多选属性: 1.html内容 multiple=”multiple” 属性为多选属性 <div clas ...

  4. UI UIBUTTON

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  5. [原创]VM虚拟机Centos6.4网络配置。

    关于虚拟机VMware 3种网络模式(桥接.nat.Host-only)的工作原理http://www.cnblogs.com/hehexiaoxia/p/4042583.html 操作环境 主机:W ...

  6. HttpContext.GetOwinContext().Authentication 报错 解决办法

    HttpContext.GetOwinContext().Authentication 会提示 不包含GetOwinContext 方法的报错信息 解决办法:引入system.web程序集,GetOw ...

  7. html、css基础注意点

    之前第一次接触html,一直使用table进行布局,十分麻烦还相当丑陋,造成当初并没有多大的兴趣,直到半年前开始接触到了使用div+css编写页面,才对它有了兴趣.作为一个菜鸟记录自己的点滴教训与收获 ...

  8. Codeforces Round #284 (Div. 2) C题(计算几何)解题报告

    题目地址 简要题意: 给出两个点的坐标,以及一些一般直线方程Ax+B+C=0的A.B.C,这些直线作为街道,求从一点走到另一点需要跨越的街道数.(两点都不在街道上) 思路分析: 从一点到另一点必须要跨 ...

  9. DotSpatial 删除图层要素

    //添加图层后,定义图层,并获取图层 //遍历要素,并进行删除 FeatureSet fs = null; fs = (FeatureSet) map1.Layers[0].DataSet; //要素 ...

  10. 使用CSS3动画模拟实现小球自由落体效果

    使用纯CSS代码模拟实现小球自由落体效果: html代码如下: <div id="ballDiv"> <div id="ball">&l ...