在这里我们选取的例题是leetcode中的第20题:有效的括号
若使括号有效则每个右括号必有对应的一个左括号。然而括号之间可能存在嵌套,并列等多种不同点组合。如果使用一些基础的枚举或者其他方法可能是行不通的(至少我不会哈哈哈哈)。基于我们学过了栈这种后入先出的抽象数据结构。那么下面由我给大家演示一下。
在此之前我们先看一下题目给出的一些提示。题目要求我们返回一个Boolean类型的变量
首先给定的字符串的长度大于1,就排除s为null的可能。接着s仅由三种括号组成。这个特点我们在下面会用到。
ArrayList<Character> list = new ArrayList();
//由于栈不断的出栈入栈我们不清楚需要多大的空间所以在这里我们使用集合替代数组
int top =-1;//栈顶元素的索引。当栈为空时等于-1.
char the;//用来承载s字符串中当前遍历到的字符
在开始遍历s字符串之前我们可以先判断s的长度是否为2的倍数。有效的括号必然成对的出现。
if (s.length()%2 !=0){
return false;
}
接下来让我们开始遍历s字符串。
for (int i = 0;i<s.length();i++){
the= s.charAt(i);
if (the ==')' ||the =='}'||the==']' ) {
if (top == -1) {
return false;
}
if (the - list.get(top) != 1 && the - list.get(top)!= 2) {
return false;
}
list.remove(top);
top--;
continue;
}
list.add(the);
top++;
}
在这里我的想法是先对当前遍历到的字符进行判断。右括号不入栈这样可以降低内存损耗。同时也减少了入栈出栈的操作稍微减少了运行时间。
当我们遍历到右括号时如果栈为空,则当前的右括号没有对应的左括号,因而return false;
如果栈不为空时我们判断栈顶的字符是否与当前字符相对应。由于s仅由三种括号组成。再根据ASCII码我们可以发现。小括号的右括号ASCII码比左括号的ASCII码大一,而中括号和大括号是右边比左边大二。因而有了第三个if,这样提高了代码的可读性,且相对于一一对应的判断,这无疑减少的判断的次数。如果程序接着运行那么删除栈顶的元素,且top--。如果the为左括号那么直接入栈。不断循环直到遍历完s。
return (top == -1);
最后我们在循环外加这样一个返回值语句。如果top == -1;则栈为空,s中的括号都可以一一对应。如果top ! = -1;则栈中有多余的左括号。
最后附上这道题的运行结果。数据挺好看的哈哈哈哈。