力扣20. 有效的括号

力扣第20题

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:

输入: “()”
输出: true
示例 2:

输入: “()[]{}”
输出: true
示例 3:

输入: “(]”
输出: false
示例 4:

输入: “([)]”
输出: false
示例 5:

输入: “{[]}”
输出: true

基本算法

首先这是个栈的问题,头插法建立链表就是建栈的过程

栈的数据结构
struct node{
	char data;
	struct node *next;
};

struct stack{
	struct node *top;
	struct node *buttom;
};
建立一个新栈
struct stack *create_stack(){
	struct stack *sk=(struct stack *)malloc(sizeof(struct stack))
	if(sk==NULL){
		return false;
	}
	sk->top=sk->buttom;
	return sk;
}
入栈

把top指针指向添加的节点,而且要让新节点的next指向之前top指向的节点

void push(struct stack *sk,char p){
	node *n=new node;
	n->data=p;
	n->next=sk->top;
	sk->top=n;
}
出栈

出栈一般有两种:1.让指定数据出栈2.让top指向的数据出栈,注意,如果要让指定的数据出栈,而且如果那个数据在中间,那你就不得不把从top到那个数据的全部节点出栈,因为栈是后进先出,而且只允许一段入/出,这里我们讨论把top指向的节点出栈

这个非常简单,你可能会马上想到

sk->top=sk->top->next;

但是如果再想一下,你虽然完成了出栈,但是出了栈的那个节点怎么办?如果你不delete它它就会一直在堆中,每出栈一次就有一个无用节点占用内存,所以我们还要设法把这个无用节点删除,因此我们需要引入一个临时变量

void pop(struct stack *sk){
	node *n=sk->top;
	sk->top=n->next;
	free(n);
}
挨个取字符串内的字符
for(int i=0;s[i];i++){
        l->data=s[i];
        printf("%c",s[i]);
        struct Lnode *l2=(struct Lnode*)malloc(sizeof(struct Lnode));
        l2->next=l;
        l=l2;
    }

解题思路

此题用链栈来解决在这里插入图片描述

struct node{
	char data;
	struct node *next;
};

struct stack{
	struct node *top;
	struct node *buttom;
};

struct stack* create_stack(){
	struct stack* sk=(struct stack *)malloc(sizeof(struct stack));
	sk->top=sk->buttom;
	return sk;
}

struct stack* push(struct stack* sk,char p){
	struct node *n=(struct node *)malloc(sizeof(struct node));
	n->data=p;
	n->next=sk->top;
	sk->top=n;
    return sk;
}

struct stack* pop(struct stack* sk){
	struct node *n=sk->top;
	sk->top=n->next;
	free(n);
    return sk;
}

bool isEmpty(struct stack *sk){
    if(sk->top==sk->buttom) return true;
    else return false;
}

bool isValid(char * s){
    struct stack *l;
    l=create_stack();
    bool is=true;
    int k=0,j=0;
    while(s[k]){
        k++;
    }
    for(int i=0;s[i];i++){
        if((s[i]=='(')||(s[i]=='{')||(s[i]=='[')){
            l=push(l,s[i]);
        }
        else if(s[i]==')'){
            if(!isEmpty(l)){
                if(l->top->data!='('){
                    is=false;break;
                }
                else l=pop(l);
            }
            else{
                is=false;break;
            }
        }
        else if(s[i]==']'){
            if(!isEmpty(l)){
                if(l->top->data!='['){
                    is=false;break;
                }
                else l=pop(l);
            }
            else{
                is=false;break;
            }
        }
        else if(s[i]=='}'){
           if(!isEmpty(l)){
                if(l->top->data!='{'){
                    is=false;break;
                }
                else l=pop(l);
            }
            else{
                is=false;break;
            }
        }
        j++;
    }
    if(k==j)is=isEmpty(l);
    else false;
    return is;
}
大神思路

算法原理

  • 栈先入后出特点恰好与本题括号排序特点一致,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,则遍历完所有括号后 stack 仍然为空;
  • 建立哈希表 dic 构建左右括号对应关系:keykey 左括号,valuevalue 右括号;这样查询 22 个括号是否对应只需 O(1)O(1) 时间复杂度;建立栈 stack,遍历字符串 s 并按照算法流程一一判断。

python

class Solution:
    def isValid(self, s: str) -> bool:
        dic = {'{': '}',  '[': ']', '(': ')', '?': '?'}
        stack = ['?']
        for c in s:
            if c in dic: stack.append(c)
            elif dic[stack.pop()] != c: return False 
        return len(stack) == 1

链接:https://leetcode-cn.com/problems/valid-parentheses/solution/valid-parentheses-fu-zhu-zhan-fa-by-jin407891080/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值