Leetcode(3) 判断字符串是否有效 及栈结构复习

在考虑这个问题前,我们首先复习数据结构中的栈,因为编译器中括号匹配就是通过栈来实现的:
栈:
栈:是一种先进后出的数据结构;其本质也就有特殊限制的链表(先进后出,栈顶),提起栈我们首先会想到什么呢?当然是进栈(push)和出栈(pop),下面我们通过代码来实现进栈和出栈过程:
我们要重视栈顶这个部分:栈顶(top),我们要保证栈顶只有一个节点,并且链接到下面的节点,具体的实现方式是,构建一个新节点,把新节点的next(指针)指向原先的栈顶,再把栈顶设置为新节点。如下面代码所示。

#建立栈结构 push 和  pop
#首先定义listnode
class node(object):
    def __init__(self,value=None):
        self.value=value
        self.next=None
class stack(object):
    def __init__(self):
        self.node=node()
        self.top=[self.node]
    def push(self,elem):
        new_node=node(elem)
        if self.top[0].value==None:
            new_node.next=None
        else:
            new_node.next=self.top[0]
        self.top.append(new_node)
        self.top.pop(0)
    def pop(self):
        try:
            value_top=self.top[0].value
            node=self.top[0].next
            self.top.append(node)
            self.top.pop(0)
            return value_top
        except:
            print('wrong')
s=stack()
for i in ['a','b','c','d']:
    s.push(i)
for i in range(4):
    print(s.pop())
        

问题和问题分析

问题来源于leetcode,
引用自leetcode
这个问题可以说非常重要,因为我们程序编译器中常常要检查括号是否配对,如果我们能够真正了解这个原理,能够有助于我们深入了解编译器原理:
我们首先考虑简单的情况:当所有括号类型相同的时候,我们只需要让每个左括号都有一个右括号与其匹配就可以,总结来说,我们将左括号计数(left)有如下公式:
l e f t + + left++ left++
我们考虑遇到右括号时,left的不同情况:

  1. left=0 说明没有和右括号相匹配的左括号,即表达式是invaild
  2. left>0,我们有与右括号相匹配的左括号,此时匹配我们要将 l e f t − − left-- left
  3. 如果遍历完所有的符号后,left!=0,说明表达式依旧是invalid

总而言之,我们只需要计数左括号,看是否有与之匹配的右括号,但是这仅仅是简单的情况,没有考虑到不同符号之间的相对位置,如果是如下这样的表达式,我们上面总结的规律就不满足了:
({)}

进一步考虑

根据一个有趣的规律:
关于有效括号表达式的一个有趣属性是有效表达式的子表达式也应该是有效表达式。(不是每个子表达式)。
在这里插入图片描述从这里我们看出是递归的,也就是如果每个子表达式是有效的表达式,整个表达式就是有效的,这样我们就可以从解决每个子表达式出发,当表达式匹配就删除,直至剩下空的表达式说明了表达式是有效的:算法流程如下:

  1. 遇到左括号将其压入栈。
  2. 遇到右括号,将栈顶推出,如果与栈顶相匹配,继续进行,如果不匹配,则可以判断整个表达式无效(invaild)。

如果最后栈空就说明了,表达式有效,代码如下,用字典的数据结构有助于我们降低复杂度:

#建立栈结构 push 和  pop
#首先定义listnode
class node(object):
    def __init__(self,value=None):
        self.value=value
        self.next=None
class stack(object):
    def __init__(self):
        self.top=None
    def push(self,elem):
        new_node=node(elem)
        if self.top==None:
            new_node.next=None
        else:
            new_node.next=self.top
        self.top=new_node
    def pop(self):
        if self.top!=None:
            value_top=self.top.value
            node=self.top.next
            self.top=node
            return value_top
        else:
            return False

string='()'
dict_={'}':'{',']':'[',')':'('}
def judge_str(str_,dict_):
    s=stack()
    for i in str_:
        if i in dict_:
            result=s.pop() if s.top else '#'
            if  (result!=dict_[i]):
                return False
        else:
            s.push(i)
    if s.top==None:
        return True
    else:
        return False
                
judge_str(string,dict_)            
 

总结

总结而言,我们括号匹配是一种递归结构,如果每个子表达式匹配,那么整个表达式也匹配,用栈结构来实现它,按照以上总结的规律,用字典格式可以很快很好的解决问题.

  1. 遇到左括号将其压入栈。
  2. 遇到右括号,将栈顶推出,如果与栈顶相匹配,继续进行,如果不匹配,则可以判断整个表达式无效(invaild)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据给定的引用内容,我们可以使用以下步骤来判断一个字符串是否有效。首先,我们可以创建一个HashMap来存储括号的匹配关系。然后,我们遍历字符串中的每个字符。如果字符是左括号,我们将其放入中。如果字符是右括号,我们检查顶元素是否与其匹配。如果匹配,我们将顶元素弹出。如果不匹配,或者为空,我们可以判断字符串无效,返回false。最后,如果遍历完字符串为空,我们可以判断字符串有效字符串,返回true。以下是具体的代码实现: ```java import java.util.HashMap; import java.util.Stack; public boolean isValid(String s) { HashMap<Character, Character> map = new HashMap<>(); map.put(')', '('); map.put(']', '['); map.put('}', '{'); Stack<Character> stack = new Stack<>(); for (char c : s.toCharArray()) { if (map.containsValue(c)) { stack.push(c); } else if (map.containsKey(c)) { if (stack.isEmpty() || stack.pop() != map.get(c)) { return false; } } } return stack.isEmpty(); } ``` 此方法通过遍历字符串中的每个字符,并利用的先入后出特性,来判断括号的匹配情况。如果遍历完字符串为空,则表示字符串有效的;否则,字符串无效。123 #### 引用[.reference_title] - *1* *2* [判断字符串是否有效](https://blog.csdn.net/qq_45838562/article/details/120488404)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *3* [leetcode: 判断字符串是否有效](https://blog.csdn.net/weixin_38426554/article/details/98469713)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值