力扣-20-有效的括号

这题看到的第一眼想法就是“栈”,因为只有最内层括号匹配了,才能匹配外层的括号

思路

要有正确的顺序,那么这样“({})”应该是非法的,“{{}}”这样应该也是非法,“(((())))”这样是否非法?不非法?
需要考虑的有两点

  1. 是否匹配
  2. 嵌套顺序

给的是一个字符串

  1. 从左到右依次扫描每一个字符,扫描到左括号(1.栈空,直接入栈;2.栈不空,判断栈顶元素优先级是否大于当前元素,大于返回非法,小于入栈)
  2. 扫描到右括号,判断与栈顶元素是否匹配,匹配则栈顶元素出栈,不匹配返回非法

有两个难点:“怎么判断优先级”以及“怎么判断匹配”,感觉要写一堆if-else了

这是一道简单题,但通过率只有40%几

  1. “{{{}}}”是合法的,“[{}]”也是合法的
  2. 如果不先判空就直接stack.top会报错

两次NG,第一次“(])”,第二次“]”
不优雅的第一版ACCEPT代码

class Solution {
public:
	bool isValid(string s) {
		stack<char> st;
		int len = s.size();
		for (int i = 0; i < len; ++i) {
			// 遇到左括号,判断压栈
			if (s[i] == '{' || s[i] == '[' || s[i] == '(') {
				st.push(s[i]);
			}
			// 遇到右括号,弹栈
			else if (s[i] == ')') {
				if (st.size() > 0) {
					if (st.top() == '(') {
						st.pop();
					}
					else {
						return false;
					}
				}
				else {
					return false;
				}
			}
			else if (s[i] == ']') {

				if (st.size() > 0) {
					if (st.top() == '[') {
						st.pop();
					}
					else {
						return false;
					}
				}
				else {
					return false;
				}
			}
			else if (s[i] == '}') {

				if (st.size() > 0) {
					if (st.top() == '{') {
						st.pop();
					}
					else {
						return false;
					}
				}
				else {
					return false;
				}
			}

		}

		// 如果栈里面还剩左括号呢
		if (st.size() != 0) {
			return false;
		}

		return true;
	}
};


内存消耗大了

题解

官方题解给出的也是用

基本思路跟我是一样的,但是给出了一些优化,比如:字符串长度为奇数时就直接返回false了,因为不可能配对

然后题解中用到了unordered_map,这个其实我也想过,看能不能替代栈

敲一遍,理解一下吧

相比之下的优点有:

  1. 通过判断字符长度减少了很多判断步骤
  2. 用unordered_map实现配对,避免了每次敲括号字符的繁琐和易出错,同时利用到了其提供的方法检查、匹配括号
  3. 最后判空我还要写个判断真是脑子抽了
  4. 为什么我想到的是size方法==0,而不是isEmpty方法?
class Solution {
public:
    bool isValid(string s) {
        int n = s.size();
        // 排除长度为奇数的情况,一定不配对
        if(n%2==1){
            return false;
        }
        // 用来配对括号
        unorder_map<char,char> pairs = {
            {')','('},
            {']','['},
            {'}','{'}
        }
        stack<char> stk;
        for(char:s){
            // 用来检查是否存在给定键的函数
            // 这也是为什么要把右括号作为键值了
            if(pairs.count(ch)){
                if(stk.empty()||stk.top()!=pairs[ch]){
                    return false;
                }
            }
            stk.pop();
        }else{
            stk.push(ch);
        }
        // 不用像我一样单独写一个判断
        return stk.empty();
    }
};


为什么好像…内存使用没什么优化的样子

后记

其实评论区还有其他的思路方法,比如ASCII码(是不是只有C++能这么用)、字符替换啥的,兴许这个思路就不是最优最巧妙的吧

posted @ 2022-05-25 20:20  YaosGHC  阅读(35)  评论(0编辑  收藏  举报