Apr.12-13 字符串解码(中等)& 砖墙(中等)

394. 字符串解码
在这里插入图片描述

思路

这题的思路跟括号匹配很像(因为这题也包含括号),都是利用栈先进后出的特性。
关键是如何处理括号的嵌套,如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())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值