LeetCode: 20. Valid Parentheses

括号匹配有效性判断
本文介绍了一种使用栈数据结构来判断字符串中括号是否有效配对的方法。通过遍历字符串,利用栈的后进先出特性,确保每种类型的括号能够正确闭合且顺序无误。文章提供了详细的代码实现,并对比了两种不同的解决方案。

0509第1题(虽然是08做的,但这会已经09了)

题目

Given a string containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.

An input string is valid if:

Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.

思路
  • 直接用一个后进先出的stack来匹配就好
class Solution {
public:
    bool isValid(string s) {
        stack<char> mystack;
        if(s.length()==1)
            return false;
        for(int i=0; i<s.length(); i++){
            if(mystack.size()==0 & (s[i]==')' || s[i]=='}' || s[i]==']'))
                return false;
            else if(s[i]=='(' || s[i]=='{' || s[i]=='[')
                mystack.push(s[i]);
            else if(s[i]=='}' & mystack.top()=='{' & mystack.size()!=0)
                mystack.pop();
            else if(s[i]==']' & mystack.top()=='[' & mystack.size()!=0)
                mystack.pop();
            else if(s[i]==')' & mystack.top()=='(' & mystack.size()!=0)
                mystack.pop();
            else 
                return false;
        }
        if(mystack.size()==0)
            return true;
        else 
            return false;      
    }
};

然后在提交过程中,发现自己老是忘了各种特殊样例,还是要多刷题鸭!
加油,你是最胖的!

刚刚去偷瞄了大佬的答案,虽然runtime和memory和我差不多,但素人家的看起来很简洁啊!

class Solution {
public:
    bool isValid(string s) {
        stack<char> paren;
        for (char& c : s) {
            switch (c) {
                case '(': 
                case '{': 
                case '[': paren.push(c); break;
                case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;
                case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;
                case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;
                default: ; // pass
            }
        }
        return paren.empty() ;
    }
};

<think>好的,我现在要仔细看看用户提供的这段Python代码,并找出其中的问题。首先,这个函数的作用是判断括号是否有效匹配,也就是LeetCode上的经典问题Valid Parentheses。用户给出的代码结构大致正确,但可能存在一些边界条件处理上的错误。 首先看代码结构:用户使用了一个字典dic来存储左括号对应的右括号,然后使用一个栈stack来处理左括号的入栈和匹配。遍历字符串中的每个字符时,如果是左括号就入栈,如果是右括号则检查栈顶的左括号是否匹配。如果匹配则弹出栈顶元素,否则返回False。最后检查栈是否为空,空则返回True,否则返回False。 但这里可能存在几个问题。首先,在判断右括号的时候,代码的顺序有问题。例如,在代码的elif条件判断中,用户先检查dic[stack[-1]] == sign,然后再检查stack是否非空。如果此时栈已经是空的,那么stack[-1]会导致索引错误。比如输入为")",这时在第一次循环时,sign是右括号,进入elif分支,但此时stack是空的,访问stack[-1]会引发IndexError。 第二个问题是在处理右括号的时候,可能没有正确处理所有情况。例如,当栈为空时遇到右括号,应该直接返回False。但原代码中的elif条件只有在栈非空的情况下才会被满足,否则会进入else分支返回False。不过,原代码中的条件顺序有问题,因为判断dic[stack[-1]] == sign是在检查栈是否非空之前,这会导致栈为空时出现错误。 具体来说,用户代码中的这一行: elif dic[stack[-1]] == sign and stack: 这里的条件判断顺序是错误的。因为在Python中,条件表达式是按顺序执行的,先执行dic[stack[-1]] == sign,这时候如果stack为空,stack[-1]就会导致IndexError。所以正确的顺序应该是先检查栈是否非空,然后再访问stack[-1]。正确的条件应该是: elif stack and dic[stack[-1]] == sign: 此外,当栈为空时遇到右括号,应该立即返回False。例如,当输入是"]",那么在循环中第一个字符就会进入else分支,导致返回False。但原代码中的elif条件在栈为空时会导致错误,所以需要调整条件顺序。 接下来,测试几个案例: 测试案例1:输入为“()”: - 处理第一个字符'(',入栈。 - 处理第二个字符')',进入elif,检查栈顶元素对应的右括号是否等于当前字符。此时栈非空,且匹配,所以弹出栈。最后栈为空,返回True。正确。 测试案例2:输入为“(()]”: - 前三个字符处理正常,栈中有'(', '('。 - 遇到']'时,检查栈顶是'(',对应的右括号是')',不等于']',所以进入else返回False。正确。 测试案例3:输入为“]”: - 第一个字符是']',进入elif或else。由于栈为空,在判断条件时,会先执行dic[stack[-1]],此时stack[-1]不存在,导致IndexError。所以代码会抛出异常而不是返回False,这是错误的。 因此,修正条件顺序是必须的。将elif的条件改为先检查栈是否非空: 原来的代码行: elif dic[stack[-1]] == sign and stack: 应改为: elif stack and dic[stack[-1]] == sign: 这样,当栈为空时,条件中的第一个表达式stack为False,整个条件不会继续判断后面的部分,避免了索引错误。 修改后的elif行应该是: elif stack and dic[stack[-1]] == sign: 另外,还要考虑当栈为空时遇到右括号的情况。例如,当输入是")"时,此时栈为空,应该直接返回False。在原代码中,进入的是else分支,返回False,所以这部分是正确的。但必须确保在判断条件时不会出现异常。 总结问题: 1. 条件判断顺序错误,导致栈为空时访问stack[-1]引发错误。 2. 在处理右括号时,需要先检查栈是否为空,再进行匹配。 修正后的代码: class Solution(object): def isValid(self, s): dic = {")": "(", "]": "[", "}": "{"} # 或者保持原样,但处理方式需要调整 stack = [] for char in s: if char in dic.values(): # 如果是左括号,入栈 stack.append(char) elif char in dic.keys(): # 如果是右括号 if stack and dic[char] == stack[-1]: # 栈不为空且匹配 stack.pop() else: return False else: return False # 无效字符 return not stack 或者保持原来的dic结构,但需要调整判断逻辑: 原dic是左括号到右括号的映射,比如dic["("] = ")"。所以在处理时,如果当前字符是右括号,需要检查是否和栈顶的左括号对应的右括号相同。例如: class Solution(object): def isValid(self, s): dic = {"(": ")", "[": "]", "{": "}"} stack = [] for char in s: if char in dic: # 左括号 stack.append(char) else: # 右括号 if not stack: # 栈为空,无法匹配 return False top = stack.pop() # 弹出栈顶元素 if dic[top] != char: # 不匹配 return False # 遍历结束后检查栈是否为空 return not stack 这样修改后的代码逻辑更清晰。处理右括号时,首先检查栈是否为空,如果是,返回False;否则弹出栈顶元素,并检查是否匹配。这样避免了原来的条件顺序问题。 原用户代码中的错误出现在elif分支的条件判断顺序,正确的做法应该是在处理右括号时,先检查栈是否为空,再进行比较。或者像第二种修改方法,直接使用pop的方式,并在pop之前检查栈是否为空。 用户代码的另一个问题是在处理右括号时,可能没有覆盖所有情况。例如,当输入包含非括号字符时,原代码可能不会处理,但题目假设输入只包含括号,但实际可能需要添加判断。不过原问题可能假设输入是有效的字符,所以可能不需要处理。 综上,用户代码的主要错误是条件判断顺序导致栈为空时的索引错误。正确的做法是调整条件顺序,或者在处理右括号时先检查栈是否为空。</think><< 该代码旨在检查括号的有效性,但存在逻辑错误和潜在运行时错误。主要问题在于条件判断顺序不当导致栈为空时访问`stack[-1]`会引发`IndexError`。以下是修正后的代码及解释: **修正后的代码**: ```python class Solution(object): def isValid(self, s): dic = {"(": ")", "[": "]", "{": "}"} stack = [] for char in s: if char in dic: # 左括号入栈 stack.append(char) else: # 处理右括号 if not stack: # 栈为空但遇到右括号,直接无效 return False top = stack.pop() # 取出栈顶左括号 if dic[top] != char: # 括号不匹配 return False return not stack # 最终栈空才有效 ``` **错误原因解释**: 1. **条件顺序错误**:原代码`elif dic[stack[-1]] == sign and stack:`中,先检查`stack[-1]`再判断`stack`是否为空。当栈为空时,`stack[-1]`会触发`IndexError`。 2. **逻辑改进**:修正后直接分离左/右括号处理逻辑。遇到右括号时: - 先检查栈是否为空(空则无效) - 再弹出栈顶元素并验证括号匹配性 **正确实现逻辑**: - 左括号直接入栈 - 右括号必须与栈顶左括号匹配 - 最终栈必须为空才能返回`True`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值