leetcode:20,题目描述:
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
方法一:栈
看了题目描述,相信大家都知道题意是要干什么了,像这类题目,首先想到的方法便是利用栈的特性来处理,遇到'('或'{'或'['就进行压栈操作,遇到')'或'}'或']'就进行出栈操作,把出栈的字符与当前遇到的字符进行比较看是否是一对,如果不是则直接返回无效。另外如果发现字符还没遍历完栈就先空了,那么也说明字符串是无效的(举个例子:"()]",这样的字符串)。
下面我们就首先使用栈的数据结构来解决这个问题
public boolean isEffective(String s) {
//先判断字符串是否为空,如果为空,那么直接返回false
if (s == null || "".equals(s)) {
return false;
}
//将字符串s转变为字符数组
char[] chars = s.toCharArray();
//我们定义一个栈来存放和移除像'('、'{'、'['这样的字符
Stack<Character> stack = new Stack<Character>();
//下面我们遍历字符数组
for (char c : chars) {
//如果当前遍历的字符是'(',那么进行压栈动作
if (c == '(') {
stack.push(c);
} else if (c == '{') {
stack.push(c);
} else if (c == '[') {
stack.push(c);
} else {
//如果字符是')'或'}'或']',那么先判断栈是不是为空,如果为空了,那么直接返回无效
if (stack.size() == 0) {
return false;
}
//如果栈中有元素,那么我们将栈顶元素取出
char top = stack.pop();
//我们将当前遍历到的字符与栈顶元素进行对比,如果发现它们两个不是一对,那么直接返回无效
if (c == ')' && top != '(') {
return false;
}
if (c == '}' && top != '{') {
return false;
}
if (c == ']' && top != '[') {
return false;
}
}
}
//遍历完字符数组后,如果栈为空说明有效,如果不为空则无效
return stack.isEmpty();
}
方法二:计数器
在方法一种,我们使用了栈的数据结构来解决问题,但是栈有个坏处就是,假如我们的字符串很长的话,大量的压栈会耗费比较大的内存,那么有没有办法绕过栈呢,答案显然是有的,我们可以利用3个计数器来分别统计'('、'{'、'['这三种字符的个数。遇到这三种字符就累加,遇到')'、'}'、']'就扣减。如果发现某种字符的计数器数量小于0了,那么说明整个字符串无效。
public boolean isEffective(String s) {
if (s == null || "".equals(s)) {
return false;
}
//将字符串转换为字符数组
char[] chars = s.toCharArray();
//定义'('对应的计数器变量为count1;
int count1 = 0;
//定义'{'对应的计数器变量为count2;
int count2 = 0;
//定义'['对应的计数器变量为count3;
int count3 = 0;
//遍历字符数组,遇到左括号就累加,遇到右括号就扣减
for (char c : chars) {
if (c == '(') {
count1++;
} else if (c == ')') {
count1--;
if (count1 < 0) {
return false;
}
} else if (c == '{') {
count2++;
} else if (c == '}') {
count2--;
if (count2 < 0) {
return false;
}
} else if (c == '[') {
count3++;
} else if (c == ']') {
count3--;
if (count3 < 0) {
return false;
}
}
}
return true;
}