难度简单
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
提示:
1 <= s.length <= 104
s
仅由括号'()[]{}'
组成
解法一
用map 存储(), [ ] , { } ,
创键一个栈, 如果是左括号就压栈,如果是右括号,就和栈顶的元素配对,能配上,就出栈左括号,配不上就false,循环完判断栈是不是空,不是空就返回true;
class Solution {
public static boolean isValid(String s) {
Deque<Character> stack=new ArrayDeque<Character>();
// push(e) addFirst(e)
// pop() removeFirst()
// peek() peekFirst()
// isEmpty() //判断是否为空
Map map = new HashMap();
map.put('(',')');
map.put('{','}');
map.put('[',']');
for (int i = 0; i < s.length(); i++) {
if(map.containsKey(s.charAt(i))){
stack.push(s.charAt(i));
}
else if(!stack.isEmpty()&&map.get(stack.peek()).equals(s.charAt(i)))
{
stack.pop();
}
else{
return false;
}
}
if(stack.isEmpty()){
return true;
}
else{
return false;
}
}
}
改进 :
不用map 直接判断,还有通过ascii码 进行匹配 左括号和右括号一般相差1或2.
class Solution {
public static boolean isValid(String s) {
Deque<Character> stack=new ArrayDeque<Character>();
// push(e) addFirst(e)
// pop() removeFirst()
// peek() peekFirst()
// isEmpty() //判断是否为空
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)=='('||s.charAt(i)=='['||s.charAt(i)=='{'){
stack.push(s.charAt(i));
}
else if(!stack.isEmpty()&&(s.charAt(i)-stack.peek()==1||s.charAt(i)-stack.peek()==2))
{
stack.pop();
}
else{
return false;
}
}
if(stack.isEmpty()){
return true;
}
else{
return false;
}
}
}
解法二
优秀的解法
将字符串转换成字符数组 ,进行遍历,如果是左括号,就直接压栈入对应的右括号,如果是右括号,就直接弹出栈顶进行比较,如果不一样就直接返回false(如果一样,因为已经弹出了就默认继续下一次循环)
class Solution {
public boolean isValid(String s) {
if (s.length() == 0) {
return true;
}
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(') {
stack.push(')');
} else if (c == '{') {
stack.push('}');
} else if (c == '[') {
stack.push(']');
} else if (stack.size() == 0 || c != stack.pop()) {
return false;
}
}
return stack.isEmpty();
}
}
笔记:
创建栈和队列:java中通常使用Deque[dɛk] 来完成队列和堆栈的功能。
Deque是个接口,其实现类有:
- ArrayDeque,使用“数组”存储数据
- LinkedList,使用“链表”存储数据
- ConcurrentLinkedDeque,线程安全的LinkedList
数据检索多的用ArrayDeque;数据需要频繁插入、更新,则用LinkedList;多线程操作使用ConcurrentLinkedDeque。
创建栈: (有stack类,不推荐用)
Deque<Integer> stack=new ArrayDeque<Integer>();
对应函数:boolean isEmpty() // 判断当前栈是否为空
synchronized E peek() //获得当前栈顶元素
synchronized E pop() //获得当前栈顶元素并删除
E push(E object) //将元素加入栈顶
synchronized int search(Object o) //查找元素在栈中的位置,由栈底向栈顶方向数
创建队列:
java中定义队列 一般这样定义: Queue<E> queue = new LinkedList<E>();
当采用LinkedList来实现时,api的使用和对用关系如下:
队列方法 等效方法
offer(e) offer(e)/offerLast(e) //进队列,将元素加入队列末尾
poll() poll()/pollFirst() //获取队列头的元素并移除
peek() peek()/peekFirst() //获取队列头的元素 isEmpty() //判断是否为空