读题
题目难度:easy
有效的括号题目包括两点:
- 同类型的左右括号一一对应;
- 左右括号以正确的顺序闭合,“正确的顺序”,按照我的理解就是同类型的右括号与前方距离最近的左括号对应闭合。
思路
从易到难,先解决单类型括号的闭合检查,然后再改为多类型混合检查。
单类型括号的闭合检查
一开始我想用两层循环判断,第一层取出当前字符串的一个符号,如果是左括号,就在第二层检查后面有没有同类型的右括号。代码如下:
class Solution {
public boolean isValid(String s) {
// Note that an empty string is also considered valid.
if (s == null)
return true;
boolean a = false;
int len = s.length();
for (int i = 0; i < len; i++) {
char ch1 = s.charAt(i);
if (ch1 == '(') {
a = false;
for (int j = i + 1; j < len; j = j + 2) {
if (s.charAt(j) == ')') {
a = true;
break;
}
}
if (!a) {
return false;
}
} else if ((ch1 == ')') && a) {
a = true;
}
}
return a;
}
}
多类型括号的闭合检查
将左括号和右括号分别放到两个数组中,并用两个数组的索引来表示是否是同一个类型的括号。不过这个第二版的代码不够完善,不能正确判断“[([])]”的情况。代码如下:
class Solution {
public boolean isValid(String s) {
if (s == null) return true;
int len = s.length();
if(len % 2 == 1) return false; //奇数长度直接出局
String leftS = "({[";
String rightS = ")}]";
boolean[] record = new boolean[len];//默认值为false
for (int i = 0; i < len; i++) {
if (!record[i]) {
String str1 = s.substring(i, i + 1);
if (leftS.contains(str1)) {
int loc = leftS.indexOf(str1);// 左括号的索引
for (int j = i + 1; j < len; j = j + 2) {
if (s.charAt(j) == rightS.charAt(loc)) {
record[i] = true;
record[j] = true;
break;
}
}
if (!record[i]) {
return false;
}
} else if ((rightS.contains(str1)) && record[i]) {
record[i] = true;
}
}
}
for(int t = 0; t < len; t++)
{
if(!record[t])
return false;
}
return true;
}
}
用stack栈的思路解决
在第二版改进的时候,对于"[([])]“这种情况,总会把第4个符号”]“和第一个符号”[“对应,而不是最近的第2个符号”[",这就是读题里的第二点,正确顺序闭合需要注意的地方。但是我一直没想好该怎么解决。经过上网查资料,网友建议用栈stack来完成。
栈
限定仅在表头进行插入和删除操作的线性表
第三版代码:
class Solution {
public boolean isValid(String s) {
// 判断是否为空
// Note that an empty string is also considered valid.
if (s == null)
return true;
int len = s.length();
if (len % 2 == 1)
return false; // 奇数长度直接出局
String[] left = { "(", "{","["};
String[] right = { ")","}","]"};
Stack theStack = new Stack(len);
int index1 = 3,index2 = 4;
for (int i = 0; i < len; i++) {
String ch1 = s.substring(i, i + 1);
if (Arrays.asList(left).contains(ch1)) {
theStack.push(ch1);
} else if (i == 0) {
System.out.println(2);
return false;
} else {
index1 = Arrays.binarySearch(left, theStack.peek());
index2 = Arrays.binarySearch(right, ch1);
if (index1 == index2) {
theStack.pop();
} else {
return false;
}
}
}
if(theStack.isEmpty()) {
return true;
}else {
return false;
}
}
class Stack {
private int maxSize;
private String[] stackArray;
private int top;
public Stack(int max) {
maxSize = max;
stackArray = new String[maxSize];
top = -1;
}
public void push(String j) {
stackArray[++top] = j;
}
public String pop() {
return stackArray[top--];
}
public String peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
}
}
在这一版中,有个问题一直没有搞明白,判断"[“和”]"在数组中的索引Index1和index2时,一直是-2而不是2,这个还没找到原因。
感想
第一次做LeetCode的题,这是一道easy级别的题,写写改改也花了一些时间,虽然不是最优的代码,但是记录下来,以后继续改进。