一.栈
1.特点:先进后出
2.自己实现一个简单的栈
public class MyStack {
public int[] elem;
public int usedSize;
public MyStack() {
this.elem=new int[10];
}
//压栈
public void push(int val){
if(isFull()){
//扩容
elem= Arrays.copyOf(elem,2*elem.length);
}
elem[usedSize]=val;
usedSize++;
}
//判满
public boolean isFull(){
return usedSize==elem.length;
}
//出栈
public int pop(){
if(isEmpty()){
throw new EmptyException("栈为空");
}
usedSize--;
return elem[usedSize];
}
//获取栈顶元素
public int peek(){
if(isEmpty()){
throw new EmptyException("栈为空");
}
return elem[usedSize-1];
}
//判空
public boolean isEmpty(){
return usedSize==0;
}
}
3.相关练习
3.1括号匹配(https://leetcode.cn/problems/valid-parentheses/)
遍历字符串,遇到左括号入栈,遇到右括号如果匹配则出栈,否则不匹配返回false;遍历玩栈为空则匹配,否则不匹配返回false;
实现:
class Solution {
public boolean isValid(String s) {
Stack<Character> stack=new Stack<>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(ch=='('||ch=='['||ch=='{'){
stack.push(ch);
}else{
if(stack.empty()){
return false;
}
if(ch==')'&&stack.peek()=='('){
stack.pop();
}else if(ch==']'&&stack.peek()=='['){
stack.pop();
}else if(ch=='}'&&stack.peek()=='{'){
stack.pop();
}else{
return false;
}
}
}
return stack.empty();
}
}
3.2逆波兰表达式求值(https://leetcode.cn/problems/evaluate-reverse-polish-notation/)
遍历后缀表达式,遇到数字入栈,遇到符号弹出栈顶两个元素,参与运算,把计算后的结果再次入栈
实现:
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack=new Stack<>();
for(int i=0;i<tokens.length;i++){
String str=tokens[i];
if(str.equals("+")){
int num2=stack.pop();
int num1=stack.pop();
stack.push(num1+num2);
}else if(str.equals("-")){
int num2=stack.pop();
int num1=stack.pop();
stack.push(num1-num2);
}else if(str.equals("*")){
int num2=stack.pop();
int num1=stack.pop();
stack.push(num1*num2);
}else if(str.equals("/")){
int num2=stack.pop();
int num1=stack.pop();
stack.push(num1/num2);
}else{
int n=Integer.parseInt(str);
stack.push(n);
}
}
return stack.pop();
}
}
3.3出栈入栈次序匹配(https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&tqId=11174&ru=/exam/oj)
遍历入栈的数组,先将入栈数组的元素入栈,然后将栈顶元素与出栈元素比较,相等的话就出栈,知道入栈数组遍历完,栈为空则次序匹配,否则不匹配。
实现:
public boolean IsPopOrder (int[] pushV, int[] popV) {
// write code here
Stack<Integer> stack=new Stack<>();
int j=0;
for(int i=0;i<pushV.length;i++){
stack.push(pushV[i]);
while(!stack.empty()&&stack.peek().equals(popV[j])&&j<popV.length){
stack.pop();
j++;
}
}
return stack.empty();
}
3.4最小栈(https://leetcode.cn/problems/min-stack/)
实现:需要维护一个最小栈minstack,压栈的时候小于等于当前最小站的val值需要压栈,minstack栈顶等于stack的栈顶的时候需要给minstack出栈。
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minstack;
public MinStack() {
stack=new Stack<>();
minstack=new Stack<>();
}
public void push(int val) {
stack.push(val);
if(minstack.empty()){
minstack.push(val);
}else{
if(minstack.peek()>=val){
minstack.push(val);
}
}
}
public void pop() {
int n=stack.pop();
if(n==minstack.peek()){
minstack.pop();
}
}
public int top() {
if(!stack.empty()){
return stack.peek();
}
return -1;
}
public int getMin() {
return minstack.peek();
}
}