leetcode 78
求解序列的所有子集。
例如: [1, 2, 3].
所有子集为:[ [ ], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3] ]
其中一种解题思路为:
使用2进制来表示,组合中是否包含某个元素。
例如 001–> [3], 101–>[1, 3], 111–>[1, 2, 3]
因此只有列出 [0, 2n) 的2进制表示,就可以求出所有的子集。
求解2进制表示时,有一个“zero left padding” 的问题。
例如 1 的二进制表示为 0b1, 但是我们需要获得:0b001
具体解决方法见下面代码。在这里也学习了bin()函数的用法。
def subsets_leetcode2(nums: List[int]) -> List[List[int]]:
n = len(nums)
nth_bit = 1 << n
output = []
for i in range(0, 2**n):
# generate bitmask from 0..00 to 1..11
# bin() will return the string of binary number.
# in order to deal with "zero left padding", we need to add 'nth_bit'.
# for example: when n = 3, bin(1) = '0b1', but we need to get '0b001'.
# Therefore, we use nth_bit(1<<3 = 8), bin(1|8) = '0b1001', so bin(1|4)[3:] = '001'
bitmask = bin(i | nth_bit)[3:]
combination = [nums[j] for j in range(n) if bitmask[j] == '1']
output.append(combination)
return output
另外,利用format函数也可以解决‘zero left padding’,例如上面代码中的:
bitmask = bin(i | nth_bit)[3:]
可以替换为:
bitmask = '{:0{width}b}'.format(i, width=n)
Format的格式定义见下面示例代码:
# /python/python-3.8.1-docs-html/library/string.html#formatexamples
# The general form of a standard format specifier is:
# format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
# fill ::= <any character>
# align ::= "<" | ">" | "=" | "^"
# sign ::= "+" | "-" | " "
# width ::= integer
# precision ::= integer
# type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
c = {'<': "left", '^': "center", '>': "right"}
for align, text in c.items():
a = '{:{fill}{align}16}'.format(text, fill="0", align=align)
print(a)
output:
left000000000000
00000center00000
00000000000right