20.有效的括号
最后更新:2024-05-11-22
链接:https://leetcode.cn/problems/valid-parentheses/description/
题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
提示:
- \(1 <= s.length <= 10^4\)
s
仅由括号 '()[]{}'
组成
解题思路
使用栈的方法,左侧括号时入栈,右侧括号时出栈,如果匹配成功,最终栈是空的
逻辑处理:
- 遇到左侧括号时,括号入栈
- 遇到右侧括号,判断右侧括号与栈顶匹配,则出栈,否则返回false
隐藏条件:
- 括号匹配,则字符个数必然是偶数
- 入栈出栈,如果遍历过半时,必然是要开始出栈的,否则就是不匹配的
- 字符全部处理完毕,如果匹配,栈必然已经是空的
C |
---|
| // 定义链表节点结构体
typedef struct Node {
char data;
struct Node* next;
} Node;
// 定义栈结构体
typedef struct Stack {
Node* top;
} Stack;
// 初始化栈
Stack* createStack() {
Stack* stack = (Stack*)malloc(sizeof(Stack));
stack->top = NULL;
return stack;
}
// 判断栈是否为空
int isEmpty(Stack* stack) {
return stack->top == NULL;
}
// 入栈操作
void push(Stack* stack, char value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = stack->top;
stack->top = newNode;
}
// 出栈操作
char pop(Stack* stack) {
if (isEmpty(stack)) {
return -1;
}
Node* temp = stack->top;
char value = temp->data;
stack->top = temp->next;
free(temp);
return value;
}
// 查看栈顶元素
char peek(Stack* stack) {
if (isEmpty(stack)) {
return -1;
}
return stack->top->data;
}
// 销毁栈,释放所有节点内存
void destroyStack(Stack* stack) {
Node* temp;
while (!isEmpty(stack)) {
temp = stack->top;
stack->top = stack->top->next;
free(temp);
}
free(stack);
}
char charPairs(char a) {
if (a == '}') return '{';
if (a == ']') return '[';
if (a == ')') return '(';
return 0;
}
bool isValid(char* s) {
unsigned int n = 0;
unsigned int i = 0;
unsigned int top = 0;
Stack *stack = NULL;
n = strlen(s);
// 必须是偶数,如果是奇数,肯定是不满足条件的
if ((n % 2) != 0) {
return false;
}
stack = createStack();
// 遍历字符串,记录top,当左侧括号出现时,入栈,top++
for (i = 0; i < n; i++) {
// 超过一半的时候,就需要开始出栈了,否则必然不匹配
if (top > n/2) {
destroyStack(stack);
return false;
}
char ch = charPairs(s[i]);
// 找到一个左侧括号,直接入栈
if (ch == 0) { // 找到左侧括号
push(stack, s[i]);
} else {
if (isEmpty(stack) || (peek(stack) != ch)) {
destroyStack(stack);
return false;
}
pop(stack);
}
}
// 如果括号是匹配的,栈一定是空的
if (isEmpty(stack)) {
return true;
}
destroyStack(stack);
return false;
}
|
C |
---|
| bool CheckBracketMatchForArr(char sL, char *stack, unsigned int *top)
{
unsigned int index = *top;
// 没有入栈,或者与栈顶不是一对,返回false
if ((index == 0) || (stack[index - 1] != sL)) {
return false;
}
// 出栈
stack[index] = '\0';
index--;
*top = index;
return true;
}
bool isValidByArray(char* s) {
unsigned int n = 0;
unsigned int i = 0;
unsigned int top = 0;
char *stack = NULL;
n = strlen(s);
// 必须是偶数,如果是奇数,肯定是不满足条件的
if ((n % 2) != 0) {
return false;
}
// 使用数组,表示栈数据存储,申请内存
stack = (char*)malloc(n);
if (stack == NULL) {
return false;
}
memset(stack,0,n);
// 遍历字符串,记录top,当左侧括号出现时,入栈,top++
for (i = 0; i < n; i++) {
// 超过一半的时候,就需要开始出栈了,否则必然不匹配
if (top > n/2) {
free(stack);
return false;
}
// 找到一个左侧括号,直接入栈
if ((s[i] == '(') || (s[i] == '{') || (s[i] == '[')) { // 找到左侧括号
stack[top] = s[i];
top++;
continue;
}
// 如果是右侧括号,当与栈顶是一对的时候,进行出栈,否则直接返回false
if ((s[i] == ')') && (CheckBracketMatchForArr('(', stack, &top) == false))
{
return false;
}
if ((s[i] == '}') && (CheckBracketMatchForArr('{', stack, &top) == false))
{
return false;
}
if ((s[i] == ']') && (CheckBracketMatchForArr('[', stack, &top) == false))
{
return false;
}
}
// 如果括号是匹配的,则top是一定为0
return top == 0;
}
bool isValid(char* s) {
return isValidByArray(s);
}
|
C |
---|
| bool CheckBracketMatchForArr(char sL, char *stack, unsigned int *top)
{
unsigned int index = *top;
// 没有入栈,或者与栈顶不是一对,返回false
if ((index == 0) || (stack[index - 1] != sL)) {
return false;
}
// 出栈
stack[index] = '\0';
index--;
*top = index;
return true;
}
char pairs(char a) {
if (a == '}') return '{';
if (a == ']') return '[';
if (a == ')') return '(';
return 0;
}
bool isValidByArrayWithParis(char* s) {
unsigned int n = 0;
unsigned int i = 0;
unsigned int top = 0;
char *stack = NULL;
n = strlen(s);
// 必须是偶数,如果是奇数,肯定是不满足条件的
if ((n % 2) != 0) {
return false;
}
// 使用数组,表示栈数据存储,申请内存
stack = (char*)malloc(n);
if (stack == NULL) {
return false;
}
memset(stack,0,n);
// 遍历字符串,记录top,当左侧括号出现时,入栈,top++
for (i = 0; i < n; i++) {
// 超过一半的时候,就需要开始出栈了,否则必然不匹配
if (top > n/2) {
free(stack);
return false;
}
char ch = pairs(s[i]);
// 找到一个左侧括号,直接入栈
if (ch != 0) { // 找到左侧括号
stack[top] = s[i];
top++;
} else {
if (CheckBracketMatchForArr(ch, stack, &top) == false) {
free(stack);
return false;
}
}
}
// 如果括号是匹配的,则top是一定为0
free(stack);
return top == 0;
}
bool isValid(char* s) {
return isValidByArrayWithParis(s);
}
|
Go |
---|
| func isValid(s string) bool {
strlen := len(s)
if strlen % 2 == 1 {
return false
}
pairs := map[byte]byte{
')': '(',
']': '[',
'}': '{',
}
var stack []byte
for i := 0; i < strlen; i++ {
// 如果在过一半的时候,top还没有开始出栈,则肯定不匹配
if (len(stack) > strlen/2) {
return false;
}
// 题目指定只有 '(',')','{','}','[',']'几个字符串,有匹配到右侧括号
if pairs[s[i]] > 0 {
// 右侧括号,如果字符串有效,则左侧括号必然已经在栈中,并且是在栈顶
if len(stack) == 0 || stack[len(stack)-1] != pairs[s[i]] {
return false
}
// 满足条件,出栈
stack = stack[:len(stack)-1]
} else {
// 不是右侧括号,入栈
stack = append(stack, s[i])
}
}
// 如果括号是匹配的,最终结果,栈一定是空的
return len(stack) == 0
}
|