这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
在家休息了2天,今天是本周第1天上班。积压了挺多事情的,感觉自己有点忙不过来了。晚上听了一个关于MAC实用小工具的分享,发现其实有意思的小技巧还挺多的,以后也要不断去发现,工具让自己“变懒”,把时间花费在更有意义的事情上。
题目
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
思路
又是一题更加偏向于数据结构而不是算法思想的题目。
首先理解一下题目,总共有3种括号,如果要字符串合法必须满意以下条件:
- 3种括号的左半边出现次数和右半边出现次数必须相等
- 对于任何一个右半边括号,在它左边出现的第一个左半边括号必须跟它是可以配对的
所以,自然而然会想到使用一个栈,如果遇到括号左半边,就进行压栈;如果遇到括号右半边,就弹出跟当前右半边看能否配对,不能配对就肯定是false,如果能配对,就继续遍历下一个。
有2个需要注意的点:
- 如果遇到右半边,需要从栈中弹出最上面的元素时,注意一下栈为空的情况
- 如果最后遍历完成后,需要判断一下栈是否是空的,如果不是空,证明左半边肯定有多的
Java版本代码
class Solution {
public boolean isValid(String s) {
Set<Character> leftSet = new HashSet<>();
leftSet.add('(');
leftSet.add('[');
leftSet.add('{');
Map<Character, Character> map = new HashMap<>();
map.put('(', ')');
map.put('[', ']');
map.put('{', '}');
Stack<Character> stack = new Stack<>();
int len = s.length();
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if (leftSet.contains(c)) {
// 如果是括号的左半边,压栈
stack.push(c);
} else {
// 如果不是,需要从栈中弹出最上面的元素比较是否能配对
if (stack.isEmpty()) {
return false;
}
char left = stack.pop();
if (c == map.get(left)) {
continue;
} else {
return false;
}
}
}
if (stack.isEmpty()) {
return true;
} else {
return false;
}
}
}