System.out.print(s.pop().val + " ");
}
}
3. 栈的OJ题
=========
1. 括号匹配(LeetCode20)有效的括号
可以进入上面链接查看题目
方法:
1. 依次拿到字符串的元素,如果该元素是左括号,则入栈
2. 如果不是左括号,先判断栈是否为空,如果为空则返回false,如果不为空则进行后续操作
3. 拿到栈顶的元素与前面所拿到字符串的元素作比较,如果括号匹配,则栈顶元素出栈,结束当前循环,继续进行后续比较,如果括号不匹配,则返回false
4. 当字符串的元素比较完后,判断栈是否有剩余,如果有剩余,则返回false,无剩余则返回true
参考代码:
class Solution {
public boolean isValid(String s) {
Stack stack = new Stack<>();
for(int i=0;i<s.leng
th();i++){
char c = s.charAt(i);
if(c==‘(’||c==‘{’||c==‘[’){
stack.push©;
}else{
if(stack.empty()){
return false;
}
char top = stack.pop();
if(top==‘{’&&c==‘}’||top==‘[’&&c==‘]’||top==‘(’&&c==‘)’){
continue;
}else{
return false;
}
}
}
if(!stack.empty()){
return false;
}
return true;
}
}
2.逆波兰表达式求值(LeetCode150)逆波兰表达式求值
可以进入上面链接查看题目
方法:
1. 依次将字符串入栈,如果字符串不是算数符号,则入栈
2. 当字符串是算数符号的时候,取栈顶的两个元素进行算数运算
3. 将运算的结果继续入栈
4. 依次进行上述循环
5. 最后返回栈顶元素的值,即所求逆波兰表达式的值
参考代码:
class Solution {
public int evalRPN(String[] tokens) {
Stack s = new Stack<>();
for(String e : tokens){
if(!(e.equals(“+”)||e.equals(“-”)||e.equals(“*”)||e.equals(“/”))){
s.push(Integer.parseInt(e));//将字符e转为整型
}else{
int right = s.pop();
int left = s.pop();
switch(e) {
case “+”:
s.push(left+right);
break;
case “-”:
s.push(left-right);
break;
case “*”:
s.push(left*right);
break;
case “/”:
s.push(left/right);
break;
}
}
}
return s.peek();
}
}
3. 出栈入栈次序匹配(JZ31)栈的压入、弹出序列
方法:
1. 当入栈序列的元素小于出栈序列的第一个元素,将入栈序列的元素依次入栈
2. 每入栈一个元素,入栈序列的下标加1
3. 当入栈序列的元素与出栈序列的元素相等时,进行出栈,并且出栈序列下标加1
4. 当出栈序列的元素遍历完后,返回true
参考代码:
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack s = new Stack<>();
int inIndex = 0;
int outIndex = 0;
while(outIndex<popped.length){
while(s.empty()||s.peek()!=popped[outIndex]){
if(inIndex<pushed.length){
s.push(pushed[inIndex]);
inIndex++;
}
else{
return false;
}
}
s.pop();
outIndex++;
}
return true;
}
}
4. 栈的模拟实现
==========
public class MyStack {
E[] array;
int size;
public MyStack(){
array = (E[])new Object[3];
}
public E push(E e){
ensureCapacity();
array[size++] = e;
return e;
}
public E pop(){
E e = peek();
size–;
return e;
}
public E peek(){
if(empty()){
throw new RuntimeException(“栈为空,无法获取栈顶元素”);
}
return array[size-1];
}
public int size(){
return size;
}
public boolean empty(){
return 0 == size;
}
private void ensureCapacity(){
if(size == array.length){
array = Arrays.copyOf(array, size*2);
}
}
}
5. 栈,虚拟机栈,栈帧的区别
================
栈:一种后进先出的数据结构,继承自Vector
虚拟机栈:具有特殊作用的一块内存空间。栈区:是线程私有的,存放的是函数调用相关信息,主要是栈帧,它是按照数据结构中栈的特性来实现的
栈帧:一种结构,与函数调用相关。内部:局部变量表,操作数栈。每个方法运行时JVM会创建一个栈帧,然后将栈帧压到虚拟机栈中,调用结束时,该方法对应的栈帧会从虚拟机栈中出栈。
ze;
}
private void ensureCapacity(){
if(size == array.length){
array = Arrays.copyOf(array, size*2);
}
}
}
5. 栈,虚拟机栈,栈帧的区别
================
栈:一种后进先出的数据结构,继承自Vector
虚拟机栈:具有特殊作用的一块内存空间。栈区:是线程私有的,存放的是函数调用相关信息,主要是栈帧,它是按照数据结构中栈的特性来实现的
栈帧:一种结构,与函数调用相关。内部:局部变量表,操作数栈。每个方法运行时JVM会创建一个栈帧,然后将栈帧压到虚拟机栈中,调用结束时,该方法对应的栈帧会从虚拟机栈中出栈。