括号匹配

leetcode20:有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串

先来初步想想:如何才算括号有效。总的来说分为“()”,“{}”,"[]"三种然后就是这几个互相嵌套。比入“[()]”,"{[()]}"等。
试着用一个简单的算法来解决这一问题。

1.我们从表达式的左侧开始,每次只处理一个括号。
2.假设我们遇到一个开括号(即 (),表达式是否无效取决于在该表达式的其余部分的某处是否有相匹配的闭括号(即 ))。此时,我们只是增加计数器的值保持跟踪现在为止开括号的数目。left += 1
3.如果我们遇到一个闭括号,这可能意味着这样两种情况:
(1)此闭括号没有与与之对应的开括号,在这种情况下,我们的表达式无效。当 left==0,也就是没有未配对的左括号可用时就是这种情况。
(2)我们有一些未配对的开括号可以与该闭括号配对。当left>0,也就是有未配对的左括号的数量。

4.当left==0 时遇到一个闭括号(例如 )),那么当前的表达式无效。否则,我们会减少 left 的值,也就是减少了可用的未配对的左括号的数量。
5.继续处理字符串,直到处理完所有括号。
6.如果最后我们仍然有未配对的左括号,这意味着表达式无效。
————————————————————————————————————————————————————————————————————
我还是一步一步来吧,上面的文字时官方给的关于计数器思路的一段文字。
我是看的迷迷糊糊的
先想想括号正常的情况就那几个,我能想到如果该字符串中若有一种(比如(),[],{})的个数为奇数则该字符串中的括号必然不匹配。
之前计数器的那个思路,当遇到一个],并不能确定有相应的[与之对应。(最近的未配对的开括号是一个花括号,而不是一个方括号,因此计数方法在这里被打破了。)
所以我还是用栈。
提到栈肯定想到栈顶栈底,所以必须先判断该栈是否为空。

1.初始化栈 S。
2.一次处理表达式的每个括号。
3.如果遇到开括号,我们只需将其推到栈上即可。这意味着我们将稍后处理它,让我们简单地转到前面的 子表达式。
4.如果我们遇到一个闭括号,那么我们检查栈顶的元素。如果栈顶的元素是一个 相同类型的 左括号,那么我们将它从栈中弹出并继续处理。否则,这意味着表达式无效。
5.如果到最后我们剩下的栈中仍然有元素,那么这意味着表达式无效。

在这里插入图片描述
下面这个是比较一般的方法,不过一般的方法,对于我来说那也不是很容易的。
如果遇到(,{,[ 中的任何一个压入栈中,否则为右括号;若为右括号,就找是否存在与之匹配的左括号。如果找到就出栈。如果不匹配,返回false;
反过来也类似。
一直持续该操作,直到栈空或者遇到终止条件返回false。

class Solution {
    public boolean isValid(String s) {
		Stack<Character> st= new Stack<>();
		for(int i=0;i<s.length();i++) {
			char si = s.charAt(i);
			if(!st.isEmpty()) {
				char c = st.peek();//将栈顶的值赋给c,peek操作不改变栈的值
				if(si=='('   ||  si=='['  ||   si=='{') {//前半段直接入栈
					st.push(si);
				}else if((si==')'&&c== '(' )||(si== ']' &&c== '[' ) ||(si=='}'&&c=='{')) {//后半段匹配;
					st.pop();
				}else {//不匹配直接返回
					return false;
				}
			}else {
				if(si==')'||si==']'||si=='}') {
					return false;
				}else {
					st.push(si);
				}
			}
		}
		if(st.isEmpty()) {
			return true;
		}else {
			return false;
		}
    }
}

下面这个是比较高效的些的算法。
通过建立hashmap,进行较为高效的操作。
左括号放在开头,保证只要是左就压入栈中;否则说明是右括号,右括号需要与栈顶元素对比,看是否匹配。

class Solution {
    public boolean isValid(String s) {
        
       char[] chars=s.toCharArray();
       Stack<Character> stack=new Stack<Character>();
       Map<Character,Character> map= new HashMap<>();
       map.put(')','(');
       map.put(']','[');
       map.put('}','{');
       for(char c:chars){
           if(!map.containsKey(c)){
              stack.push(c);
           }
           else if(stack.isEmpty() || map.get(c)!=stack.pop()){
               return false;
           }
       }
       return stack.isEmpty();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值