面试题1
题目
改变元素的序列
1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A: 1,4,3,2
B: 2,3,4,1
C: 3,1,4,2
D: 3,4,2,1
答案:C
2.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的顺
序是( )。
A: 12345ABCDE
B: EDCBA54321
C: ABCDE12345
D: 54321EDCBA
答案:B
面试题2
题目
将递归转化为循环 如:逆序打印链表
1.递归
public void display2(Node pHead){
if (pHead == null){
return;
}
if(pHead.next == null){
System.out.print(pHead.val+" ");
return;}
display2(pHead.next);
System.out.print(pHead.val+" ");
}
图解:
2.循环的方式:使用栈,先进后出
public void display3(Node pHead){
Stack<Node> stack = new Stack<>();
Node cur = head;
while (cur!=null){
stack.push(cur);
cur = cur.next;
}
while(!stack.isEmpty()){
Node top = stack.pop();
System.out.print(top.val+" ");
}
}
面试题3
题目
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/valid-parentheses
思路
使用栈进行解答
遍历字符串成字符
判断字符是否为括号,是左括号就进栈,遇到右括号时,字符ch2接收栈顶元素为ch2
判断ch2(左括号)与ch(右括号)是否匹配,匹配就将ch2进行出栈,不匹配返回false
最后判断栈是否为空,不为空就说明栈内的左括号没有匹配完,左括号多,返回false。
排除以上情况,返回true
代码实现
public class IsValid {
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 {
//遇见了右括号,1.判断栈里面还有有没有元素,没有就无法匹配这个右括号,返回false
if(stack.empty()){
return false;
}
// 遇见了右括号,1. 判断栈里面还有元素,判断左括号和这个右括号是否配对,配对就出栈,不配对就false
char ch2 = stack.peek();
if(ch == ')' && ch2 == '(' ||ch == ']' && ch2 == '['||ch == '}' && ch2 == '{'){
stack.pop();
}else {
return false;
}
}
}
if (!stack.empty()){
// 遍历完成,如果栈里面还有元素,则没有配对成功
return false;
}
// 排除所有的false 返回true
return true;
}
}
面试题4
题目
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。
注意:
有效的算符为 '+'、'-'、'*' 和 '/' 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式,答案及所有中间计算结果可以用 32 位 整数表示。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation
思路
使用栈进行解答
遍历字符串
判断是否为运算符 isOperation(String x)
不是运算符进行入栈操作(记得转化为Integer类型(Integer.parseInt(x)))
是运算符进行出站操作两次分别使用num2接收第一次出站的元素,num1接收第二次出站的元素
进入switcht语句进行判断运算符的类型,进行计算。
进行运算num1(运算符)num2, 将运算出的结果进行进栈操作,例如:stack.push(num1+num2);break
遍历结束,栈内还剩下一个元素,直接返回该元素即可。
代码实现
package Stack;
import java.util.Stack;
/**
* Created with IntelliJ IDEA.
* Description:逆波兰表达式求值
* User: YAO
* Date: 2023-03-15
* Time: 16:35
*/
public class EvalRPN {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String x:tokens) {
// 判断是否为运算符,不是运算符选择进栈
if (!isOperation(x)){
stack.push(Integer.parseInt(x));
}else {
// 出栈操作:num1(操作符)num2
int num2 = stack.pop();
int num1 = stack.pop();
switch (x){
case "+":
stack.push(num1+num2);
break;
case "-":
stack.push(num1-num2);
break;
case "*":
stack.push(num1*num2);
break;
case "/":
stack.push(num1/num2);
break;
}
}
}
// 此时栈顶元素就是所求值
return stack.peek();
}
private boolean isOperation(String x) {
// 判断是否为运算符
return x.equals("+") || x.equals("-") || x.equals("/") || x.equals("*");
}
}
面试题5
题目
栈的压入、弹出序列
描述:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
1. 0<=pushV.length == popV.length <=1000
2. -1000<=pushV[i]<=1000
3. pushV 的所有数字均不相同
来源:牛客
思路
遍历数组pushA,
首先进行进栈操作
定义j=0;用来记录数组popA元组的下标。
比较popA元素与栈顶元素是否相等,如果相等(stack.peek().equals(popA[j] == true)),进行出栈操作,j进行++,不相等继续进行进栈操作。前提是遍历的次数不能超过数组popA的长度以及栈不能为空。
最后循环结束,检查栈是否为空,不为空说明popA不是出栈序列。
代码实现
package Stack;
import java.util.Stack;
/**
* Created with IntelliJ IDEA.
* Description:栈的弹出压入序列
* User: YAO
* Date: 2023-03-15
* Time: 16:46
*/
public class isPopOrder {
public boolean IsPopOrder(int [] pushA,int [] popA) {
Stack<Integer> stack = new Stack<>();
int j = 0;
for (int i = 0; i < pushA.length; i++) {
stack.push(pushA[i]);
while (!stack.empty()&& j<popA.length && stack.peek().equals(popA[j])){
stack.pop();
j++;
}
}
return stack.empty();
}
}
面试题6
题目
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。实现 MinStack 类:
1.MinStack() 初始化堆栈对象。
2.void push(int val) 将元素val推入堆栈。
3.void pop() 删除堆栈顶部的元素。
4.int top() 获取堆栈顶部的元素。
5.int getMin() 获取堆栈中的最小元素
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/min-stack
思路
定义两个栈 stack minStack
首先先往stack栈内压栈元素val
进栈:判断minStack栈内是否有元素,没有元素就将该val进行压栈到minStack,minStack栈内有元素,将该栈顶元素与val进行比较,如果val小于等于minStack栈顶元素,对于minStac进行压栈操作minstack.push(val);.
出栈:stack正常出栈,但是要和minStack的栈顶元素进行比较,如果相等的话,就代表最小值有变化,对于minStack进行出栈操作,minstack.push(val);
top():判断stack是否为空,不为空返回栈顶元素,为空可以返回-1,也可以设置为抛出异常
getMin():判断minStack是否为空,不为空返回栈顶元素,为空可以返回-1,也可以设置为抛出异常
代码实现
package Stack;
import java.util.Stack;
/**
* Created with IntelliJ IDEA.
* Description:最小栈
* User: YAO
* Date: 2023-03-15
* Time: 15:42
*/
public class minStack {
public Stack<Integer> stack;
public 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() {
if (!stack.empty()){
Integer val = stack.pop();
//维护最小栈
if (val.equals(minstack.peek())){
// 如果
minstack.pop();
}
}
}
public int top() {
if(!stack.empty()){
return stack.peek();
}
return -1;
}
public int getMin() {
if(!minstack.empty()){
return minstack.peek();
}
return -1;
}
}