验证平衡括号的其他方法是什么?

时间:2017-11-02 12:53:19

标签: algorithm stack

堆栈如何非常重要的经典例子是验证一串括号是否平衡的问题。你从一个空堆栈开始,你继续推送/弹出堆栈中的元素,最后,检查你的堆栈是否为空,如果是,则返回该字符串确实是平衡的。

但是,我正在寻找其他效率较低的方法来解决此问题。我想通过首先提出解决问题的指数/非线性算法向我的学生展示堆栈数据结构的有用性,然后介绍堆栈解决方案。是否有人熟悉除基于堆栈的方法之外的其他方法?

3 个答案:

答案 0 :(得分:2)

找到最后一个开头 - 括号,看它是否关闭,以及后面是否没有其他类型的括号。 如果是,请重复此过程,直到字符串为空。 如果字符串在过程结束时不为空,或者您找到不同类型的括号 - 则表示它不平衡。

示例:

([[{}]])

最后一个开头是{,所以在找到之后查找} - 从字符串中删除它并继续: ([[]])

如果字符串看起来像那样:

([[{]}])

所以在找到最后一个打开的({)之后 - 你会看到在右括号之前有一个来自不同类型(])的括号 - 所以它不平衡。

最糟糕的案例复杂性:O(n^2)

答案 1 :(得分:1)

我认为,出于教学目的,最好显示一个他们可能真正想出的简单算法?如果是这样,那么我认为一个非常直观的算法是删除()的出现,直到没有更多要删除:

boolean isBalancedParens(String s) {
    while (s.contains("()")) {
        s = s.replace("()", "");
    }
    return s.isEmpty();
}

在对所调用的各种方法的性能的合理假设下,这将采用最坏情况 O n 2 )时间和 O n )额外空间。

答案 2 :(得分:0)

如果你的学生已经熟悉递归,这里有一个简单的想法:查看第一个括号,找到所有匹配的右括号,并为这些对中的每一个,用它们内部的子串和它们后面的子串递归。 ;例如:

input:        "{(){[]}()}[]"  
option 1:      ^     ^  
recurse with: "(){[]" and "()}[]"  

              "{(){[]}()}[]"  
option 2:      ^        ^  
recurse with: "(){[]}()" and "[]"  

如果输入为空字符串,则返回true。如果输入以右括号开头,或者输入不包含与第一个括号匹配的右括号,则返回false。



function balanced(input) {
    var opening = "{([", closing = "})]";
    if (input.length == 0)
        return true;
    var type = opening.indexOf(input.charAt(0));
    if (type == -1)
        return false;
    for (var pos = 1; pos < input.length; pos++) { // forward search
        if (closing.indexOf(input.charAt(pos)) == type) {
            var inside = input.slice(1, pos);
            var after = input.slice(pos + 1);
            if (balanced(inside) && balanced(after))
                return true;
        }
    }
    return false;
}
document.write(balanced("{(({[][]}()[{}])({[[]]}()[{}]))}"));
&#13;
&#13;
&#13;

使用前向搜索更适合短平衡子串的连接;对于深度嵌套的字符串,使用向后搜索更好。但两者最坏的情况是O(n 2 )。