代码短很重要吗?精细,有的时候确实重要……especially, for Python.
今天要写点其他东西,只写3题,保证不鸽
0089题 格雷编码【Gray Code】
题目:
格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。格雷编码序列必须以 0 开头。
示例:
输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2
对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。
00 - 0
10 - 2
11 - 3
01 - 1
输入: 0
输出: [0]
解释: 我们定义格雷编码序列必须以 0 开头。
给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。
因此,当 n = 0 时,其格雷编码序列为 [0]。
题目相对严谨
除Robust以外无需注意太多
解题思路:
这道题一开始看样例没看懂为什么可以有两种解,之后想了一下明白了,是因为题目给出对本题格雷码的构造只要change一位就可以了,按照这样理解的话,如果是3位或者4位的话,结果的可能性也是非常巨大的。所以我们还是专注于从后往前构造格雷码。
class Solution:
def grayCode(self, n):
res = [0]
cnt = 0
while cnt <= n-1:
cnt += 1
m = len(res)
transfer = 1 << cnt - 1
for i in range(m-1, -1, -1):
res.append(res[i]|transfer)
return res
0090题 子集 II【Subsets II】
题目:
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
题目相对严谨
除空集等Robust情况需要额外注意以外,其他无需考虑太多
解题思路:
这题又是一道续集题目,初代见:https://blog.csdn.net/bright_silmarillion/article/details/80759018
在python中,初代的方法也可以用于这道题目,只要保证存入数据有序,并check就好
class Solution:
def subsetsWithDup(self, nums):
n = len(nums)
if n == 0: return [[]]
res = []
for i in range(1<<n):
tmp = []
for j in range(n):
if i & (1<<j):
tmp.append(nums[j])
if sorted(tmp) not in res:
res.append(sorted(tmp))
return res
然而这道题这种方法并不一定是最快的,因为in
这个运算所需要的复杂度,我们并不能估计,按照最坏情况来看,这种算法的复杂度也应该是
级别的,而如果普通来看的话,这道题有没有一边去重一边添加的
的复杂度呢,实际上是有的,不过仍然需要搜索,代码如下:
class Solution:
def __init__(self):
self.res = []
def make(self, index, path, n, nums):
self.res.append(path[:])
if index > n: return
for i in range(index, n):
if i > index and nums[i] == nums[i-1]: continue
self.make(i+1, path+[nums[i]], n, nums)
def subsetsWithDup(self, nums):
nums.sort()
self.make(0,[],len(nums),nums)
return self.res
0091题 解码方法【Decode Ways】
题目:
一条包含字母 A-Z 的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
示例:
输入: "12"
输出: 2
解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。
输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
题目不严谨之处:
1. 如果输入数据是”0“呢?如果没有解法该如何?
无需注意太多
解题思路:
这题很有用处,让我想到当年高考完之后还想去选密码学专业呢……2333
不用多说,很简单的动态规划,设长度+1的板子,然后每个板子统计板子之前有多少种解法,直接post代码:
class Solution:
def numDecodings(self, s):
n = len(s)
d = [1]+[0]*n
if s[0] == '0':
d[1] = 0
else:
d[1] = 1
for i in range(1,n):
if s[i] != '0': d[i+1] += d[i]
if s[i-1] != '0' and (s[i-1]+s[i]) <= '26': d[i+1] += d[i-1]
return d[n]