Leetcode题解 0024期

代码短很重要吗?精细,有的时候确实重要……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这个运算所需要的复杂度,我们并不能估计,按照最坏情况来看,这种算法的复杂度也应该是 O ( 2 2 n ) 级别的,而如果普通来看的话,这道题有没有一边去重一边添加的 O ( 2 n ) 的复杂度呢,实际上是有的,不过仍然需要搜索,代码如下:

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]

猜你喜欢

转载自blog.csdn.net/bright_silmarillion/article/details/80803163