LeetCode: 20. Valid Parentheses

本文介绍了一种使用栈来判断括号是否正确配对的有效方法。该算法通过遍历输入字符串并利用栈的数据结构特性,能够高效地确定括号序列是否合法。文章提供了详细的C++实现代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a string containing just the characters  '(' ')' '{' '}' '['  and  ']' , determine if the input string is valid.
The brackets must close in the correct order,  "()"  and  "()[]{}"  are all valid but  "(]"  and  "([)]"  are not.

在dicussion中看到的思想:使用stack来进行字符串匹配,联想,与编译原理中使用堆栈来进行语法分析同理操作!!!

C++:
#include <stack>
class Solution {
public:
bool isValid(string s) {
stack<char> stacklist;
for(char& c : s){
switch(c){
case '(':
case '[':
case '{':stacklist.push(c);break;
case ')':
if(stacklist.empty()||stacklist.top()!='(')
return false;
else
stacklist.pop();
break;
case ']':
if(stacklist.empty()||stacklist.top()!='[')
return false;
else
stacklist.pop();
break;
case '}':
if(stacklist.empty()||stacklist.top()!='{')
return false;
else
stacklist.pop();
break;
default: ;
}
}
return stacklist.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、付费专栏及课程。

余额充值