leetcode 刷题笔记之——20.有效的括号valid-parentheses

题目描述:

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

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:
输入: "()"
输出: true

示例 2:
输入: "()[]{}"
输出: true

示例 3:
输入: "(]"
输出: false

示例 4:
输入: "([)]"
输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses

解题思路

1. 利用计数的方法统计是否左右括号的数量是否匹配

设定int型变量 left、right,统计左右括号的数量,判断其是否相等(方法很笨)
另外一种是设定一个int变量称之为left,初始值为0。
遍历整个字符串,出现一个左括号则变量+1,出现一个右括号则变量-1,最后left变量为0则说明左右括号数量相等,反之亦然。

分析:第二个思路有效统计了左右括号的数量关系,但是没有考虑到位置逻辑关系,仍无法解决问题,参考示例4。

既要考虑数量关系,又要考虑逻辑关系,应该怎么做?

2. 利用栈的方法,FILO先进后出的特性

给定一个栈,遍历整个字符串。
若为左括号则push进入栈中;若为右括号则pop出栈顶的符号,判断其是否为同类型的左括号。
若匹配则进行下一个字符的判断,若不匹配则将右括号push进栈。
遍历整个字符串,若栈为空则字符串有效,若栈非空则字符串无效。
复杂度分析
时间复杂度:O(n),因为我们一次只遍历给定的字符串中的一个字符并在栈上进行 O(1) 的推入和弹出操作。
空间复杂度:O(n),当我们将所有的开括号都推到栈上时以及在最糟糕的情况下,我们最终要把所有括号推到栈上。例如 ((((((((((

该方法的代码:

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        stack = [] 
        mapping = {')':'(','}':'{',']':'['}
        for chars in s:
            if chars in mapping.values():
                stack.append(chars)
            if chars in mapping.keys():
                top_element = stack.pop() if stack else 'a'
                if mapping[chars] != top_element:
                    return False
        return not stack 

3.循环消消乐

在乐扣此题评论下有一个很有意思的写法。代码非常的简洁,眼前一亮。
主要思路很简单,通过循环不断消除字符串中的 (),[],{}的字符串。如果字符串是合法的,那么最终消除完的字符串必是一个空串,如果字符串非法则最终的字符串非空。

代码如下:

class Solution:
    def isValid(self, s):
        while '{}' in s or '()' in s or '[]' in s:
            s = s.replace('{}', '')
            s = s.replace('[]', '')
            s = s.replace('()', '')
        return s == ''

复杂度分析
时间复杂度:O(n 2 ),在每次循环语句的判断中,都要进行时间复杂度为O(n)的一次查找,查找字符串中是否有以上三个字符串。在合法字符串的情况下的该循环一共执行 n/2 次,故其时间复杂度较高。
空间复杂度:O(1),代码中没有申请额外的变量空间

你可能感兴趣的:(leetcode 刷题笔记之——20.有效的括号valid-parentheses)