利用栈思想解决括号匹配问题

1,181 阅读2分钟

题目:

leetcode问题

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

思路

利用栈,遍历字符串,如果字符为'(','[','{',就入栈,如果为')',']','}',就需要取出栈顶的元素与次字符进行匹配,如果匹配,就说明配对,在进行下一个字符的匹配,如果不匹配,说明不符合要求(根据括号的性质来的,都是成对出现)

C语言实现

bool isValid(char * s){
    if (s == NULL || s[0] == '\0') return true;
    //利用栈,声明一段空间,top相当于栈顶指针
    char *stack = (char*)malloc(strlen(s)+1); int top =0;
    for (int i = 0; s[i]; ++i) {
        if (s[i] == '(' || s[i] == '[' || s[i] == '{') stack[top++] = s[i];
        else {
            if ((--top) < 0)                      return false;//先减减,让top指向栈顶元素
            if (s[i] == ')' && stack[top] != '(') return false;
            if (s[i] == ']' && stack[top] != '[') return false;
            if (s[i] == '}' && stack[top] != '{') return false;
        }
    }
    return (!top);
}

malloc: 动态分配内存,返回一个指针(指向内存空间)

java实现

  • 版本1: 用数组实现栈
class Solution {
    public boolean isValid(String s) {

        // 空字符串
        if (s.length() == 0)
            return true;
        // 排除奇数长度(位运算)
        if ((s.length() & 1) == 1)
            return false;

        // 栈元素个数
        int index = 0;
        // 栈
        char[] stack = new char[s.length()];

        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i)) {
                case '(':
                case '[':
                case '{':
                    // 进栈
                    stack[index++] = s.charAt(i); 
                    continue;
                case ')':
                    if (index == 0 || stack[--index] != '(')
                        return false;
                    // stack[--index] == '(' ,才会contniue
                    // --index:相当于满足的元素出栈
                    continue;
                case ']':
                    if (index == 0 || stack[--index] != '[')
                        return false;
                    continue;
                case '}':
                    if (index == 0 || stack[--index] != '{')
                        return false;
                    continue;
            }
        }

        return index == 0; // 判断栈是否为空
    }
}

借鉴自LeetCode,总体思想也是利用栈,但细节操作的很好,很nice

学到了: 先排除特殊情况,减少不必要的代码消耗,再利用栈思想解决问题

charAt(): 用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。

  • 版本2: 利用栈来实现
class Solution {
    public boolean isValid(String s) {
        if (s.length() == 0)
            return true;
        if ((s.length() & 1) == 1)
            return false;
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i)) {
                case '(':
                case '[':
                case '{':
                    stack.push(s.charAt(i));
                    continue;
                case ')':
                    if (stack.isEmpty() || stack.pop() != '(')
                        return false;
                    continue;
                case ']':
                    if (stack.isEmpty() || stack.pop() != '[')
                        return false;
                    continue;
                case '}':
                    if (stack.isEmpty() || stack.pop() != '{')
                        return false;
                    continue;
            }
        }
        return stack.isEmpty();
    }
}

总结

自己欠缺的很多,对于基础知识不牢靠,思考问题不全面,希望继续加油