是一种特殊的线性表,只能在进行操作
- 往栈中元素的操作,一般叫做
- 从栈中元素的操作,一般叫做(只能移除栈顶元素,也叫做:弹出栈顶元素)
- 后进先出的原则,Last In First Out,LIFO
栈的接口设计
int size(); // 元素的数量
boolean isEmpty(); // 是否为空
void push(E element); // 入栈
E pop(); // 出栈
E top(); // 获取栈顶元素
因为栈是从栈顶添加元素,那么我们可以直接利用之前实现的ArrayList或者LinkedList来实现栈,都是从最后添加元素。这里使用动态数组和双向链表来实现栈性能都是一样的,都是O(1),因为都是往最后添加元素。
直接继承ArrayList或者LinkedList
public class Stack<E> extends ArrayList<E>{
public void push(E element) {
add(element);
}
public E pop() {
return remove(size -1);
}
public E top() {
return get(size -1);
}
}
这里直接继承,会有一些问题,因为继承后,那么这个栈都集成了父类的其他方法,这样并不是合理。所有最好是实现组合来实现栈。
public class Stack<E>{
private List<E> list = new ArrayList<>();
public int size() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public void push(E element) {
list.add(element);
}
public E pop() {
return list.remove(size() -1);
}
public E top() {// 官方的是peek()
return list.get(size() -1);
}
public void clear() {
list.clear();
}
}
Leetcode题
20. 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
方法一:利用字符串操作
public boolean isValid(String s) {
while(s.contains("()") || s.contains("[]") || s.contains("{}")){
if(s.contains("()")){
s = s.replace("()","");
}
if(s.contains("{}")){
s = s.replace("{}","");
}
if(s.contains("[]")){
s = s.replace("[]","");
}
}
return s.isEmpty();
}
方法二:使用栈实现
/**
* 1、遇见左字符,将左字符入栈
* 2、遇见右字符
* 2.1、如果栈是空的,说明括号无效
* 2.2、如果栈不为空,将栈顶字符出栈,与右字符之匹配
* 2.2.1、如果左右字符不匹配,说明括号无效
* 2.2.2、如果左右字符匹配,继续扫描下一个字符
* 3、所有字符扫描完毕后
* 3.1、栈为空,说明括号有效
* 3.2、栈不为空,说明括号无效
*/
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i =0;i < s.length();i++) {
char c = s.charAt(i);
if(c == '(' || c == '{' || c == '[') {// 左括号
stack.push(c);
}else{// 右括号
if(stack.isEmpty()) return false;
char left = stack.pop();
if(left == '(' && c != ')') return false;
if(left == '[' && c != ']') return false;
if(left == '{' && c != '}') return false;
}
}
return stack.isEmpty();
}
方法三:使用栈和Map实现
public boolean isValid02(String s) {
Map<Character, Character> map = new HashMap<>();
map.put('(',')');
map.put('[',']');
map.put('{','}');
Stack<Character> stack = new Stack<>();
for(int i =0;i < s.length();i++) {
char c = s.charAt(i);
if(map.containsKey(c)) {// 左括号
stack.push(c);
}else{// 右括号
if(stack.isEmpty()) return false;
if(c != map.get(stack.pop())) return false;
}
}
return stack.isEmpty();
}