思路
这题的思路跟括号匹配很像(因为这题也包含括号),都是利用栈先进后出的特性。
关键是如何处理括号的嵌套,如3[a2[c]]。
我们每一次遇到 ‘[’ ,就将[res, mult]压入栈,其中res是之前保存的字符串,mult是 ‘[’ 前的乘数。
以3[a2[c]]为例:
初始化res为’’,mult=0
遇到数字,则令mult = mult * 10 + int(l),这样是为了处理l为两位数的情况;
3 [ a 2 [ c ] ]
↑
l
遇到 ‘[’,将[res, mult]压入栈,也就是[’’, 3],同时初始化res为’’,mult为0;
3 [ a 2 [ c ] ]
↑
l
stack = [['', 3]]
遇到字母,res + l = ‘a’
3 [ a 2 [ c ] ]
↑
l
stack = [['', 3]]
遇到数字,则令mult = mult * 10 + int(l) = 2
3 [ a 2 [ c ] ]
↑
l
stack = [['', 3]]
遇到 ‘[’,将[res, mult]压入栈,也就是[‘a’, 2],同时初始化res为’’,mult为0;
3 [ a 2 [ c ] ]
↑
l
stack = [['', 3], ['a', 2]]
遇到字母,res + l = ‘c’
3 [ a 2 [ c ] ]
↑
l
stack = [['', 3], ['a', 2]]
遇到 ‘]’,把stack的末尾弹出,得到res_before = ‘a’, mult_curr = 2。
则 res = res_before + mult_curr * res = ‘acc’
3 [ a 2 [ c ] ]
↑
l
stack = [['', 3]] →pop→ ['a', 2]
遇到 ‘]’,把stack的末尾弹出,得到res_before = ‘’, mult_curr = 3。
则 res = res_before + mult_curr * res = ‘accaccacc’
3 [ a 2 [ c ] ]
↑
l
stack = [] →pop→ ['', 3]
# python3
class Solution:
def decodeString(self, s: str) -> str:
res, mult = '', 0
stack = list()
for l in s:
if l == '[':
stack.append([res, mult])
res, mult = '', 0
elif l == ']':
res_before, mult_curr = stack.pop()
res = res_before + mult_curr * res
elif '0' <= l <= '9':
# 解决两位数的情况
mult = mult * 10 + int(l)
else:
res += l
return res
554. 砖墙
提示:
- 每一行砖块的宽度之和应该相等,并且不能超过 INT_MAX。
- 每一行砖块的数量在 [1,10,000] 范围内, 墙的高度在 [1,10,000] 范围内, 总的砖块数量不超过 20,000。
思路
暴力方法比较容易想到,这里记录一种巧妙解法。
哈希表法:
在这种方法中,我们使用哈希表 mapmap 来保存记录 (sum, count),这里 sum 是当前行累积的砖头宽度, count 是 sum 对应的穿过砖头数目。
我们来看一看过程是如何进行的。我们逐一遍历墙的每一行,对于每一块砖,我们将当前行遇到的所有砖头的宽度加起来得到 sum,如果这个 sum 在 map 中没有出线过,我们创建一个初始 count 值为 1 的相应条目。如果 sum 已经存在于哈希表中,我们只需要给对应的 count 加一。
这个过程的原理基于以下观察:我们在遍历同一行的时候不会遇到相同的 sum 两次。所以如果 sumsum 在遍历过程中遇到相同的值,说明一定存在别的行 sum 也是那些行的衔接处。所以对应的 count 值需要加一。
对于每一行,我们只考虑到倒数第二块砖头的 sum 值,因为最后一块砖头的右边界不是一个衔接处。
最后,我们从哈希表中找到最大的 count 值,用这个值求出垂直竖线穿过的最少砖块数。
# python3
class Solution:
def leastBricks(self, wall: List[List[int]]) -> int:
if not wall:
return 0
h = len(wall)
dic = dict()
for i in range(h):
Sum = 0
for j in range(len(wall[i])-1):
Sum += wall[i][j]
if Sum in dic:
dic[Sum] += 1
else:
dic[Sum] = 1
# 为了解决[[1],[1],[1]]的情况
return len(wall) if not dic else h - max(dic.values())