前言
提示:以下是本篇文章正文内容,下面案例可供参考
1、用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
①void push(int x) 将元素 x 推到队列的末尾
②int pop() 从队列的开头移除并返回元素
③int peek()返回队列开头的元素
④boolean empty() 如果队列为空,返回 true ;否则,返回 false
class MyQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public MyQueue() {
stack1=new Stack<>();
stack2=new Stack<>();
}
public void push(int x) {
stack1.push(x);
}
public int pop() {
if(!stack2.empty())
return stack2.pop();
while (!stack1.isEmpty())
stack2.push(stack1.pop());
return stack2.pop();
}
//peek指的是队列的第一个元素奥!!!
public int peek() {
if(!stack2.empty())
return stack2.peek();
while (!stack1.isEmpty())
stack2.push(stack1.pop());
return stack2.peek();
}
public boolean empty() {
return stack1.empty() && stack2.empty();
}
}
2、用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
①void push(int x) 将元素 x 压入栈顶。
②int pop() 移除并返回栈顶元素。
③int top() 返回栈顶元素。
④boolean empty() 如果栈是空的,返回 true ;否则,返回 false
//直接使用Deque
//关于Queue与Deque的区别:https://blog.csdn.net/qq_41101966/article/details/127833999
class MyStack {
Deque<Integer> deque;
public MyStack() {
deque=new LinkedList<>();
}
public void push(int x) {
deque.addLast(x);
}
public int pop() {
return deque.removeLast();
}
public int top() {
return deque.peekLast();
}
public boolean empty() {
return deque.isEmpty();
}
}
3、最小值栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
①MinStack() 初始化堆栈对象。
②void push(int val) 将元素val推入堆栈。
③void pop() 删除堆栈顶部的元素。
④int top() 获取堆栈顶部的元素。
⑤int getMin() 获取堆栈中的最小元素。
//最小栈
//一个tips就是对于minstack每次都放入的是当前最小的
class MinStack {
Stack<Integer> stack;
Stack<Integer> minstack;
public MinStack() {
stack=new Stack<>();
minstack=new Stack<>();
}
public void push(int val) {
stack.push(val);
if(minstack.isEmpty())
minstack.push(val);
else minstack.push(Math.min(minstack.peek(),val));
}
public void pop() {
stack.pop();
minstack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minstack.peek();
}
}
4、用栈实现括号匹配
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
①左括号必须用相同类型的右括号闭合。
②左括号必须以正确的顺序闭合。
③每个右括号都有一个对应的相同类型的左括号
class Solution {
public boolean isValid(String s) {
int len=s.length();
if(len%2==1) return false;
Stack<Character> stack=new Stack<>();
for(int i=0;i<len;++i){
char c=s.charAt(i);
if(c=='(' || c=='{' || c=='[')
stack.push(c);
else {
if(stack.isEmpty()) return false; //"))" 注意这里
if(c==')') {
if(stack.pop()!='(') return false;
}
if(c=='}') {
if(stack.pop()!='{') return false;
}
if(c==']') {
if(stack.pop()!='[') return false;
}
}
}
//注意这里是要判空的!!
if(stack.isEmpty()) return true;
else return false;
}
}
5、数组中元素与下一个比它大的元素之间的距离
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
//其中cur是当前遍历到的位置;
//pre是在其前面的某个;
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int len=temperatures.length;
Stack<Integer> stack=new Stack<>();
int[] res=new int[len];
for(int cur=0;cur<len;++cur){
while (!stack.isEmpty() && temperatures[cur]>temperatures[stack.peek()]){
int pre=stack.pop();
res[pre]=cur-pre;
}
stack.push(cur);
}
return res;
}
}
6、循环数组中比当前元素大的一个元素
给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
//跟上面那个题目的思想很类似,但是这个更“难”一点;
//循环数组用2*n就解决了
//而且要注意:Arrays.fill(res, -1);因为如果不存在就返回-1;
//注意:cur%len
//注意是while
class Solution {
public int[] nextGreaterElements(int[] nums) {
int len=nums.length;
int[] res=new int[len];
Arrays.fill(res, -1);
Stack<Integer> stack=new Stack<>();
for(int cur=0;cur<len*2;++cur){
while(!stack.isEmpty() && nums[cur%len]>nums[stack.peek()]){ //这里是while
res[stack.pop()]=nums[cur%len];
}
if(cur<len)
stack.push(cur);
}
return res;
}
}
总结
这部分题目并不多,主要是要注意终止条件吧。