格雷编码(位运算,数学)
格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。即使有多个不同答案,你也只需要返回其中一种。
格雷编码序列必须以 0 开头。
示例 1:
输入: 2
输出: [0,1,3,2]
解释:00 - 001 - 111 - 310 - 2对于给定的 n,其格雷编码序列并不唯一。例如,[0,2,3,1] 也是一个有效的格雷编码序列。00 - 010 - 211 - 301 - 1
示例 2:
输入: 0
输出: [0]
解释: 我们定义格雷编码序列必须以 0 开头。给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。因此,当 n = 0 时,其格雷编码序列为 [0]。
选项代码:
class Solution(object):
def grayCode(self, n):
"""
:type n: int
:rtype: List[int]
"""
res = [0]
for i in range(n):
for j in reversed(range(len(res))):
res.append(res[j] + (1 << i))
return res
if __name__ == "__main__":
s = Solution()
print (s.grayCode(2))
扩展:格雷码
典型的二进制格雷码(Binary Gray Code)简称格雷码,因1953年公开的弗兰克·格雷(Frank Gray,18870913-19690523)专利“Pulse Code Communication”而得名,当初是为了通信,现在则常用于模拟-数字转换和位置-数字转换中。法国电讯工程师波特(Jean-Maurice-Émile Baudot,18450911-19030328)在1880年曾用过的波特码相当于它的一种变形。1941年George Stibitz设计的一种8元二进制机械计数器正好符合格雷码计数器的计数规律。
格雷码(Gray code)曾用过Grey Code、葛莱码、葛兰码、格莱码、戈莱码、循环码、二进制反射码、最小差错码等名字,它们有的是错误的,有的易与其它名称混淆,建议不再使用它们。
码表
编辑 播报
格雷码有多种编码形式
十进制数 | 4位自然二进制码 | 4位典型格雷码 | 十进制余三格雷码 | 十进制空六格雷码 | 十进制跳六格雷码 | 步进码 |
0 | 0000 | 0000 | 0010 | 0000 | 0000 | 00000 |
1 | 0001 | 0001 | 0110 | 0001 | 0001 | 00001 |
2 | 0010 | 0011 | 0111 | 0011 | 0011 | 00011 |
3 | 0011 | 0010 | 0101 | 0010 | 0010 | 00111 |
4 | 0100 | 0110 | 0100 | 0110 | 0110 | 01111 |
5 | 0101 | 0111 | 1100 | 1110 | 0111 | 11111 |
6 | 0110 | 0101 | 1101 | 1010 | 0101 | 11110 |
7 | 0111 | 0100 | 1111 | 1011 | 0100 | 11100 |
8 | 1000 | 1100 | 1110 | 1001 | 1100 | 11000 |
9 | 1001 | 1101 | 1010 | 1000 | 1000 | 10000 |
10 | 1010 | 1111 | ---- | ---- | ---- | ---- |
11 | 1011 | 1110 | ---- | ---- | ---- | ---- |
12 | 1100 | 1010 | ---- | ---- | ---- | ---- |
13 | 1101 | 1011 | ---- | ---- | ---- | ---- |
14 | 1110 | 1001 | ---- | ---- | ---- | ---- |
15 | 1111 | 1000 | ---- | ---- | ---- | ---- |
表中典型格雷码具有代表性。若不作特别说明,格雷码就是指典型格雷码,它可从自然二进制码转换而来。
特点
编辑 播报
- 格雷码属于可靠性编码,是一种错误最小化的编码方式。因为,虽然自然二进制码可以直接由数/模转换器转换成模拟信号,但在某些情况,例如从十进制的3转换为4时二进制码的每一位都要变,能使数字电路产生很大的尖峰电流脉冲。而格雷码则没有这一缺点,它在相邻位间转换时,只有一位产生变化。它大大地减少了由一个状态到下一个状态时逻辑的混淆。由于这种编码相邻的两个码组之间只有一位不同,因而在用于方向的转角位移量-数字量的转换中,当方向的转角位移量发生微小变化(而可能引起数字量发生变化时,格雷码仅改变一位,这样与其它编码同时改变两位或多位的情况相比更为可靠,即可减少出错的可能性。
- 格雷码是一种绝对编码方式,典型格雷码是一种具有反射特性和循环特性的单步自补码,它的循环、单步特性消除了随机取数时出现重大误差的可能,它的反射、自补特性使得求反非常方便。
- 由于格雷码是一种变权码,每一位码没有固定的大小,很难直接进行比较大小和算术运算,也不能直接转换成液位信号,要经过一次码变换,变成自然二进制码,再由上位机读取。 [3]
- 典型格雷码是一种采用绝对编码方式的准权码,其权的绝对值为2^i-1(设最低位i=1)。
- 格雷码的十进制数奇偶性与其码字中1的个数的奇偶性相同。
2、删除排序链表中的重复元素(链表)
存在一个按升序排列的链表,给你这个链表的头节点 head
,请你删除所有重复的元素,使每个元素 只出现一次 。
返回同样按升序排列的结果链表。
示例 1:
输入:head = [1,1,2]
输出:[1,2]
示例 2:
输入:head = [1,1,2,3,3]
输出:[1,2,3]
提示:
- 链表中节点数目在范围
[0, 300]
内 -100 <= Node.val <= 100
- 题目数据保证链表已经按升序排列
选项代码:
3、最小覆盖子串(哈希表,字符串)
给你一个字符串 s
、一个字符串 t
。返回 s
中涵盖 t
所有字符的最小子串。如果 s
中不存在涵盖 t
所有字符的子串,则返回空字符串 ""
。
注意:如果 s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
示例 2:
输入:s = "a", t = "a"
输出:"a"
提示:
1 <= s.length, t.length <= 10
5
s
和t
由英文字母组成
进阶:你能设计一个在 o(n)
时间内解决此问题的算法吗?
以下程序实现了这一功能,请你填补空白处内容:
class Solution(object):
def minWindow(self, s, t):
ls_s, ls_t = len(s), len(t)
need_to_find = [0] * 256
has_found = [0] * 256
min_begin, min_end = 0, -1
min_window = 100000000000000
for index in range(ls_t):
need_to_find[ord(t[index])] += 1
count, begin = 0, 0
for end in range(ls_s):
end_index = ord(s[end])
if need_to_find[end_index] == 0:
continue
has_found[end_index] += 1
if has_found[end_index] <= need_to_find[end_index]:
count += 1
if count == ls_t:
begin_index = ord(s[begin])
____________________________;
if window_ls < min_window:
min_begin = begin
min_end = end
min_window = window_ls
if count == ls_t:
return s[min_begin:min_end + 1]
else:
return ''
if __name__ == '__main__':
s = Solution()
print(s.minWindow('a', 'a'))
选项解答:
关键区别在26行:window_ls = end - begin + 1
class Solution(object):
def minWindow(self, s, t):
ls_s, ls_t = len(s), len(t)
need_to_find = [0] * 256
has_found = [0] * 256
min_begin, min_end = 0, -1
min_window = 100000000000000
for index in range(ls_t):
need_to_find[ord(t[index])] += 1
count, begin = 0, 0
for end in range(ls_s):
end_index = ord(s[end])
if need_to_find[end_index] == 0:
continue
has_found[end_index] += 1
if has_found[end_index] <= need_to_find[end_index]:
count += 1
if count == ls_t:
begin_index = ord(s[begin])
while need_to_find[begin_index] == 0 or \
has_found[begin_index] > need_to_find[begin_index]:
if has_found[begin_index] > need_to_find[begin_index]:
has_found[begin_index] -= 1
begin += 1
begin_index = ord(s[begin])
window_ls = end - begin + 1
if window_ls < min_window:
min_begin = begin
min_end = end
min_window = window_ls
if count == ls_t:
return s[min_begin:min_end + 1]
else:
return ''
if __name__ == '__main__':
s = Solution()
print(s.minWindow('ADOBECODEBANC', "ABC"))
PS: Python ord() 函数
原文:https://www.runoob.com/python/python-func-ord.html
Python 内置函数
描述
ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
语法
以下是 ord() 方法的语法:
ord(c)
参数
- c -- 字符。
返回值
返回值是对应的十进制整数。
实例
以下展示了使用 ord() 方法的实例:
>>>ord('a') 97 >>> ord('b') 98 >>> ord('c') 99