LeetCode专题 --- 1、有效的括号(Valid Parentheses)

前言

马上要面临毕业找工作,对于计算机专业的学生来说,刷LeetCode是必经一步,一是为了应对专业笔试题,二是复习数据结构、算法的相关知识,对于面试也有好处,现在开此专栏记录自己的刷题过程。在正式开始刷题之前,在网上看了好多诸如“如何正确打开LeetCode”之类的文章经验,其中lucifer(知乎用户)总结的十分详细,而且给出比较完整的进阶路线,所以这里跟着大佬的脚步,把大佬总结的经典题目先过一遍,附上大佬的Github

1、有效的括号(Valid Parentheses)

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

有效字符串需满足:

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

示例 1:

输入: "()"
输出: true

示例 2:

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

示例 3:

输入: "(]"
输出: false

示例 4:

输入: "([)]"
输出: false

示例 5:

输入: "{[]}"
输出: true

题目就是判断给定的只包含 '(',')','{','}','[',']' 的字符串,是否为有效字符串,即所有的括号都可以按照规则组合。

解法一:

初看到这个题目,一个比较直观的想法就是,第一个有效的组合(即两个字符正确组成括号)一定是紧邻的两个字符。如果出现这样的组合,我将其从字符串中删掉,之后第二个有效组合也一定是紧邻的两个字符,以此类推,按照这样的方式判断,只需要判断相邻的两个字符是否构成有效组合(说的比较绕,可以结合具体例子理解)。

所以第一种解法(我的最初解法):从左到右读取这个字符串,每次读取的字符存储到一个list当中,当list的长度大于等于2的时候,就判断list中最新进入的两个字符能否构成一个有效的组合(正确组成括号),如果构成有效的组合,就从list中删去,如果不能构成有效组合,就继续读取。当遍历完这个字符串之后,如果是有效字符串,那么所有的括号都可以正确组合,所以list长度最终为0;否则list长度不为0,表示不是有效字符串。代码如下:

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        s_list = list(s)
        temp = []
        for i in range(len(s_list)):
            temp.append(s_list[i])
            if len(temp) > 1:
                isDelete = self.isSame(temp[-2],temp[-1])
                if isDelete:
                    _ = temp.pop()
                    _ = temp.pop()
        if len(temp) == 0:
            return True
        else:
            return False

    def isSame(self, c_left, c_right):
        if (c_left == '(' and c_right == ')') or (c_left == '{' and c_right == '}') or (c_left == '[' and c_right == ']'):
            return True
        else:
            return False

逻辑是正确的,不过在代码实现的时候,遇到一个问题还是记录一下。因为每次如果两个相邻的字符可以正确组合,那需要从List中删除。python删除list中的元素有三种方式:

1、remove()

remove(parameter) 函数用于移除列表中某个值的第一个匹配项。其中,parameter为元素值。

aList = [123, 'xyz', 'zara', 'abc', 'xyz'];

aList.remove('xyz');  # aList = [123, 'zara', 'abc', 'xyz'];

2、pop()

pop(parameter)函数用于移除list中指定索引位置的元素。其中,parameter为索引值,如果为空默认删除list中最后一个元素。

aList = [123, 'xyz', 'zara', 'abc', 'xyz'];

top_element = aList.pop(1);  

# top_element = 'xyz'
# aList = [123, 'zara', 'abc', 'xyz'];

3、del()

del[索引数] 函数删除指定索引数的元素,还可以用来删除整个list;但是del是python语句,而不是列表方法,无法通过list来调用。

aList = [123, 'xyz', 'zara', 'abc', 'xyz'];

del aList[1];  

# aList = [123, 'zara', 'abc', 'xyz'];

最开始实现的时候,在删除元素部分,也就是代码14、15行,使用的是remove(temp[-1]),导致bug,排查了好久o(╯□╰)o。

解法二:

官方的解法,使用栈的思想(后进先出),因为在进行判断是否构成正确组合的时候,触发条件是当读取到闭括号的时候;所以解法的流程如下:

  1. 初始化一个空栈
  2. 遍历字符串,如果是开括号,进栈;如果是闭括号,栈顶元素出栈,且判断是否与当前读取到的元素构成括号;如果构成,接着读取字符串中的下一字符;如果不构成括号,返回False。
  3. 字符串遍历完毕,如果栈为空,则为有效字符串;否则为无效字符串。  

代码部分如下:

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        stack = []
        # 右括号作为key;左括号作为value
        mapping = {')':'(','}':'{',']':'['}

        for char in s:
            # 如果是右括号进栈;取栈顶元素进行匹配
            if char in mapping:
                top_element = stack.pop() if stack else '#'
                if mapping[char] != top_element:
                    return False
            # 如果是左括号,直接进栈
            else:
                stack.append(char)
        return not stack

复杂度分析:

时间复杂度:O(n),因为我们一次只遍历给定的字符串中的一个字符并在栈上进行 O(1) 的推入和弹出操作。
空间复杂度:O(n),当我们将所有的开括号都推到栈上时以及在最糟糕的情况下,我们最终要把所有括号推到栈上。例如 ((((((((((。

解法三:

在评论区还看到一个更为简便的代码,所谓简便是指代码量少,简洁易懂;不过在执行的时候,在LeetCode上面超出时间限制。

不过能想出这样的解法,也足以说明其对python的熟练程度以及对问题的深刻理解,代码如下:

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        while "()" in s or "{}" in s or "[]" in s:
            s.replace("()","")
            s.replace("{}","")
            s.replace("[]","")
        return s==""

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值