土豆炒青椒
土豆炒青椒

「脸书」边看边刷 678 ~ 有效的括号字符串

为了码工界的世界杯,奋战到底

基本信息

  • 题号:678
  • 题厂:脸书
  • 难度系数:中



字符串由 ( , ),*组成,如果有效返回 True,无效返回 False……

那什么是有效的字符串???

  • 圆括号()成对出现,即 ( 要出现在 )的前面
  • * 可以根据情况替换为 ( 或 )或 空字符串
例如 s = "(*)"
返回 True, 这时把 * 当作空字符串 

再例如 s = "(*))" 
同样返回 True,这时要把 * 当作 ( 与后面的 )配对


解题思路

  • 字符括号配对题,首先想到 stack:当遇到 ( 时,把 ( 存入 stack,遇到 ) 时再从 stack pop 出来与之配对
  • 为了实现更多配对,优先从 ( 里面配对,没有 ( 时再从 * 里面配对。所以需要准备两个 stack 分别存 ( 和 *
  • 当 ) 完成配对后,( 如果有剩,还需要把剩余 ( 与 * 配对

class Solution:
    def checkValidString(self, s: str) -> bool:
        # 创建 2 个 stack,分别存出现( 和 * 的 index
        left = []
        star = []
        
        # 遍历字符串时,如果遇上( 或 *,将它们存入 stack
        # 遇上 )时,优先于( 配对,再和 * 配对。如果( 和 * 都无法配对,可提前返回 False
        for i in range(len(s)):
            if s[i] == "(":
                left.append(i)
            elif s[i] == "*":
                star.append(i)
            else:
                if left:
                    left.pop()
                elif star:
                    star.pop()
                else:
                    return False
                
        # i: index left; j: index star
        i = j = 0
        # 如果( 还有剩,再 * 配对,此时 * 当做 )使用
        # 能与( 配对的 * 需要满足 index 大于 star。如果不能满足,可以提前返回 False
        while i < len(left):
            while j < len(star) and star[j] < left[i]:
                j += 1
            
            # find a pair of (*, move both i and j 
            if j < len(star) and star[j] > left[i]:
                i += 1
                j += 1
            else:
                return False
        
        return True


Constraints

  • 1 <= s.length <= 100
  • s[i] is '(', ')' or '*'.


Big O

  • Time:O(n)
  • Space:O(n)创建了 stack




测试

  • 字符串为 1 时

……



总结

  • 简单档 stack 组装变形「贪心」后升级成了中档!!!
CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…
加载中…

发布评论