给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 判断条件如下:
- 左括号必须与相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 空字符串被认为是有效字符串。
思路
一个有效的字符串括号必定会成对出现,因此对于一个有效的字符串而言,任意一个左括号必定可以在其后的某个位置找到和它配对的右括号,这个规则对所有整个字符串都有效。
因此如果假定一个字符串是有效的,对于非空字符串一定存在至少一对相邻配对的左右括号,比如 "({[]})","()[]{}" 这两个有效字符串均存在至少一对相邻的配对括号。假如我们拿掉相邻配对的括号,那么剩余的字符串也会出现至少一对相邻的配对括号。
接下来我们的目标就可以调整到找到这一对相邻的括号,然后一次配对,如同消消乐一般,直到整个字符串中配对的括号全部被拿掉,如果此时剩余的是一个空字符串,那么这就是一个有效的字符串。毫无疑问栈是最方便进行“消消乐”操作的数据结构。
栈 (stack)
堆栈(英语:stack)又称为栈或堆叠,是计算机科学中的一种抽象数据类型,只允许在有序的线性数据集合的一端(称为堆栈顶端,英语:top)进行加入数据(英语:push)和移除数据(英语:pop)的运算。因而按照后进先出(LIFO, Last In First Out)的原理运作。
堆栈使用两种基本操作:推入(压栈,push)和弹出(弹栈,pop):
- 推入:将数据放入堆栈顶端,堆栈顶端移到新放入的数据。
- 弹出:将堆栈顶端数据移除,堆栈顶端移到移除后的下一笔数据。
接下来我们要做的,就是遍历整个字符串,不断的将前面的字符串压入栈底,如果找到要传入的字符和栈顶的字符配对,则将两个字符消除。我们可以得到如下判断逻辑:
- 右括号如果不能在栈顶找到配对的左括号,则整个字符串是无效字符串;
代码
class Solution:
def isValid(self, s: str) -> bool:
stack = []
pair = {
')': '(',
']': '[',
'}': '{'
}
for char in s:
# 栈为空时右括号先入必然不配对
if len(stack) == 0:
if pair.get(char) is not None:
return False
# 栈不为空时右括号进入
if pair.get(char) is not None:
if stack[0] == pair[char]:
stack.pop(0)
else:
return False
else:
# 左括号不做判断, 直接入栈
stack.insert(0, char)
# 遍历完毕后栈为空说明有效
return len(stack) == 0