2021/5/22 刷题笔记有效的括号与栈

Posted 黑黑白白君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021/5/22 刷题笔记有效的括号与栈相关的知识,希望对你有一定的参考价值。



有效的括号

【题目】

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

  • 有效字符串需满足:
    • 左括号必须用相同类型的右括号闭合。
    • 左括号必须以正确的顺序闭合。

示例 1:

  • 输入:s = “()”
  • 输出:true

示例 2:

  • 输入:s = “()[]{}”
  • 输出:true

示例 3:

  • 输入:s = “(]”
  • 输出:false

示例 4:

  • 输入:s = “([)]”
  • 输出:false

示例 5:

  • 输入:s = “{[]}”
  • 输出:true

提示:

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}'组成

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【我的方法】

1、由于左括号必须以正确的顺序闭合,所以用栈存储左括号,然后遇到右括号则进行比较。
2、类型需要匹配,所以用到字典。

class Solution:
    def isValid(self, s: str) -> bool:
        stack=[]
        dic={
            '[':']',
            '(':')',
            '{':'}'
        }
        for i in s:
            if i in dic.keys():
                stack.append(i)
            else:
                if stack:
                    top=stack.pop()
                else:
                    return False
                if dic[top]!=i:
                    return False
        if stack:
            return False
        else:
            return True
# 执行用时:36 ms, 在所有 Python3 提交中击败了86.90%的用户
# 内存消耗:14.9 MB, 在所有 Python3 提交中击败了60.73%的用户
  • python中栈的实现:

    • 栈是一种线性数据结构,用先进后出或者是后进先出的方式存储数据,栈中数据的插入删除操作都是在栈顶端进行。
    • 常见栈的函数操作:
      • empty() – 返回栈是否为空 – Time Complexity : O(1)
      • size() – 返回栈的长度 – Time Complexity : O(1)
      • top() – 查看栈顶元素 – Time Complexity : O(1)
      • push(g) – 向栈顶添加元素 – Time Complexity : O(1)
      • pop() – 删除栈顶元素 – Time Complexity : O(1)
    • python中栈可以用以下三种方法实现:
      • list
        • python的内置数据结构list可以用来实现栈
          • 用append()向栈顶添加元素
          • pop() 可以以后进先出的顺序删除元素。
        • 列表不断扩大的时候会遇到速度瓶颈.列表是动态数组,因此往其中添加新元素而没有空间保存新的元素时,它会自动重新分配内存块,并将原来的内存中的值复制到新的内存块中.这就导致了一些append()操作会消耗更多的时间。
      • collections.deque
      • queue.LifoQueue
  • Python 字典(Dictionary)

    • 字典是另一种可变容器模型,且可存储任意类型对象。
      • 字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 。
      • 值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
    • 注意:如果用字典里没有的键访问数据,会输出错误。
    • 基础操作:

      • 新建/修改键值对:dict['Age'] = 8
      • 删除条目:del dict['Name'] # 删除键是'Name'的条目
      • 清空:dict.clear() # 清空字典所有条目
      • 删除字典:del dict # 删除字典

    • 内置函数和方法:

      • 计算字典元素个数,即键的总数:len(dict)
      • 返回指定键的值(如没有则返回None):dict.get(key)
      • 以列表返回一个字典所有的键:dict.keys()
      • 以列表返回字典中的所有值:dict.values()
      • 以列表返回可遍历的(键, 值) 元组数组:dict.items()
      • 删除字典给定键 key 所对应的值,返回值为被删除的值:pop(key[,default])
        • key值必须给出。 否则,返回default值。

【其他方法】

非常巧妙,从内往外一对对消解掉,最后检查是否还有落单的。

class Solution:
    def isValid(self, s: str) -> bool:
        while('()' in s or '[]' in s or '{}' in s):
            s=s.replace('{}','')
            s=s.replace('()','')
            s=s.replace('[]','')
        if s=='':
            return True
        else:
            return False
# 执行用时:40 ms, 在所有 Python3 提交中击败了68.86%的用户
# 内存消耗:14.9 MB, 在所有 Python3 提交中击败了51.13%的用户
  • python replace函数

    str.replace(old, new[, max])
    
    • Python replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
    • 返回字符串中的 old(旧字符串) 替换成 new(新字符串)后生成的新字符串,如果指定第三个参数max,则替换不超过 max 次。


有效的括号字符串(类似的编程题)

【题目】

给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

  • 任何左括号 ( 必须有相应的右括号 )。
  • 任何右括号 ) 必须有相应的左括号 ( 。
  • 左括号 ( 必须在对应的右括号之前 )。
  • * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
  • 一个空字符串也被视为有效字符串。

示例 1:

  • 输入: “()”
  • 输出: True

示例 2:

  • 输入: “(*)”
  • 输出: True

示例 3:

  • 输入: “(*))”
  • 输出: True

链接:https://www.nowcoder.com/questionTerminal/2a9453b8c4a74b11a360edce506df26d?orderByHotValue=1&page=1&onlyReference=false
来源:牛客网

  • 主要思路:

    • 同样利用栈存储,但由于只有一种括号类型,故不需要字典或者哈希表。需要两个栈分别对应( 和 *。
    • 注意,像’ * (’ 这种情况不是有效括号,所以需要用两个栈来分别存储 ‘(’ 和 ‘*’ 这两个符号的索引。
    • 遍历字符数组“
      • 遇到左括号则将其索引放入左括号栈,遇到星号则将其索引放入星号栈。
      • 遇到右括号,优先比对左括号栈,再比对星号栈,如果两个都空了,则说明右括号多了。
      • 比对完成后,如果左括号剩的比星号多,则也为False。
      • 否则需要看有无 *( 的情况。
  • 代码:

    # @param s string字符串 
    # @return bool布尔型
    #
    class Solution:
        def checkValidString(self , s ):
            # write code here
            stack1=[]
            stack2=[]
            for i in range(len(s)):
                if s[i]=='(':
                    stack1.append(i)
                elif s[i]=='*':
                    stack2.append(i)
                else:
                    if stack1:
                        stack1.pop()
                    elif stack2:
                        stack2.pop()
                    else:
                        return False
            if len(stack2)<len(stack1):
                return False
            while(stack1):
                if stack1[-1]>stack2[-1]:
                    return False
                else:
                    stack1.pop()
                    stack2.pop()
            return True
    


【部分内容参考自】

  • python中栈的实现:https://www.cnblogs.com/laozhanghahaha/p/12302836.html
  • 有效的括号字符串-leetcode 白话高效的解题思路附详细代码注释:https://blog.csdn.net/aa5305123/article/details/82807736
  • 有效的括号字符串:https://blog.csdn.net/liuxiang15/article/details/82156506

以上是关于2021/5/22 刷题笔记有效的括号与栈的主要内容,如果未能解决你的问题,请参考以下文章

刷题4:有效的括号

持续更新力扣刷题笔记

持续更新力扣刷题笔记

LeetCode刷题-20.有效括号(JS)

LeetCode刷题20-简单-有效的括号

LeetCode刷题20-简单-有效的括号