【LeetCode】Gray Code
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的更多相关文章
- 【leetcode】Gray Code (middle)
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
- 【题解】【排列组合】【回溯】【Leetcode】Gray Code
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
- 【Leetcode】【Medium】Gray Code
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
- 【LeetCode】回溯法 backtracking(共39题)
[10]Regular Expression Matching [17]Letter Combinations of a Phone Number [22]Generate Parentheses ( ...
- 【LeetCode】392. Is Subsequence 解题报告(Python)
[LeetCode]392. Is Subsequence 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/is-subseq ...
- 【LeetCode】722. Remove Comments 解题报告(Python)
[LeetCode]722. Remove Comments 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/remove-c ...
- 【LeetCode】831. Masking Personal Information 解题报告(Python)
[LeetCode]831. Masking Personal Information 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzh ...
- 【LeetCode】Minimum Depth of Binary Tree 二叉树的最小深度 java
[LeetCode]Minimum Depth of Binary Tree Given a binary tree, find its minimum depth. The minimum dept ...
- 【Leetcode】Pascal's Triangle II
Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3 ...
随机推荐
- 删除win8的网络连接记录
打开注册表,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles,修改各个子项里的P ...
- IE订阅博客
思来想去,qq邮箱订阅似乎也不是很方便,尝试了下,点击“博客”中的“订阅”,博客竟然被ie订阅了,据介绍,博客中有更新,即时IE不打开,也会看到信息,这不,我来尝试了,RSS真是不试不知道,一试真方便 ...
- python【5】-生成式,生成器
一.条件和循环 1. if语句 if <条件判断1>: <执行1> elif <条件判断2>: <执行2> else: <执行4> 例如: ...
- Galera集群server.cnf参数调整--前言
文档安排: 前言部分会简述下galera集群,正文中会针对我们线上的环境,在不断业务的情况下,进行参数调整的话,有些参数不能够进行配置,会以#***的形式写入配置文件中,文档也会进行进一步说明. 如果 ...
- [转]EntityFramework状态变化AutoDetectChangesEnabled与SaveChanged参数说明
一.约定OnModelCreating 有一些限制需要注意,例如:1.表名不支持使用标签进行标注2.最小长度在 OnModelCreating 中不支持3.正则表达式在 OnModelCreating ...
- C# 中的 Static
今天测试了一下C#中 static 的初始化顺序: 1.调用时才初始化, 2.按照调用顺序初始化 3.先执行类的静态方法,然后初始化静态变量及方法 4.继承时,先执行子类的静态方法,然后执行父类的静态 ...
- 对COM 组件的调用返回了错误 HRESULT E_FAIL
.net ppt转pdf时报以下错误: 对COM 组件的调用返回了错误 HRESULT E_FAIL 在服务器端打开PPT,选项--另存为--PDF,发现PowerPoint报了个错误: “无法找到打 ...
- spring IOC装配Bean(注解方式)
1 Spring的注解装配Bean (1) Spring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean (2) Spring的框架中提供了与@Componen ...
- 《Pro Express.js》学习笔记——概述
要学Node.js,先学Express.js. Express.js是Node.js官方推荐的基础框架. Express.js框架经过一系列的发展,已经到了4.x版本.新的版本解决了3.x之前版本的依 ...
- angular初步认识一
最近比较流行MVC前端框架开发,最近研究了一个框架AngularJS框架 不说那么多,先上例子,我是个代码控 <!DOCTYPE html> <html lang="en& ...