栈与队列数据结构:
例题1:用队列实现栈
解法1:双队列的题解思路
主要是一个push就调换一下队列。
class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
/** Initialize your data structure here. */
public MyStack() {
queue1=new LinkedList<>();
queue2=new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
queue2.offer(x);
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
Queue<Integer> temporary=new LinkedList<>();
temporary=queue1;
queue1=queue2;
queue2=temporary;
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue1.poll();
}
/** Get the top element. */
public int top() {
return queue1.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue1.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
解法2:单队列的题解思路:
class MyStack {
Queue<Integer> queue;
/** Initialize your data structure here. */
public MyStack() {
queue = new LinkedList<Integer>();
}
/** Push element x onto stack. */
public void push(int x) {
int size=queue.size();
queue.offer(x);
for(int i=0;i<size;i++){
queue.offer(queue.poll());
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.poll();
}
/** Get the top element. */
public int top() {
return queue.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
例题2:用栈实现队列
解法1:
class MyQueue {
Stack<Integer> s1;
Stack<Integer> s2;
/** Initialize your data structure here. */
public MyQueue() {
s1=new Stack<>();
s2=new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
while (!s1.isEmpty())
s2.push(s1.pop());
s2.push(x);
while (!s2.isEmpty())
s1.push(s2.pop());
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
return s1.pop();
}
/** Get the front element. */
public int peek() {
return s1.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return s1.empty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
解法2:
class CQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public CQueue() {
stack1=new Stack<>();
stack2=new Stack<>();
}
public void appendTail(int value) {
stack1.push(value);
}
public int deleteHead() {
if(stack2.empty()){
while(!stack1.empty()){
int temp=stack1.pop();
stack2.push(temp);
}
}
if(stack2.size()==0){
return -1;
}else{
return stack2.pop();
}
}
}
/**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.appendTail(value);
* int param_2 = obj.deleteHead();
*/
例题3:每日温度
解法1:遍历+跳跃
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n=temperatures.length;
int[] result=new int[n];
for(int i=n-2;i>=0;--i){
for(int j=i+1;j<n;j+=result[j]){
if(temperatures[i]<temperatures[j]){
result[i]=j-i;
break;
}
if(result[j]==0){
result[i]=0;
break;
}
}
}
return result;
}
}
解法2:栈
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n=temperatures.length;
int[] result=new int[n];
Stack<Integer> stack=new Stack<>();
for(int i=0;i<n;++i){
while(!stack.isEmpty()&&temperatures[stack.peek()]<temperatures[i]){
int prevIndex=stack.pop();
result[prevIndex]=i-prevIndex;
}
stack.push(i);
}
return result;
}
}
例题4:包含min函数的栈
class MinStack {
Stack<Integer> stack;
Stack<Integer> minStack;
/** initialize your data structure here. */
public MinStack() {
stack=new Stack<>();
minStack=new Stack<>();
}
public void push(int x) {
stack.push(x);
if(minStack.isEmpty()||minStack.peek()>x){
minStack.push(x);
}else{
minStack.push(minStack.peek());
}
}
public void pop() {
stack.pop();
minStack.pop();
}
public int top() {
return stack.peek();
}
public int min() {
return minStack.peek();
}
}
例题5:栈的压入、弹出序列
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack=new Stack<>();
int pushedIndex=0,poppedIndex=0;
while(poppedIndex<popped.length){
while(stack.isEmpty()||stack.peek()!=popped[poppedIndex]){
if(pushedIndex==pushed.length){
break;
}
stack.push(pushed[pushedIndex++]);
}
if(stack.peek()!=popped[poppedIndex]){
break;
}
stack.pop();
++poppedIndex;
}
if(stack.isEmpty()&&poppedIndex==popped.length){
return true;
}
return false;
}
}
例题6:有效的括号
class Solution {
public boolean isValid(String s) {
//初始化map
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 ch=s.charAt(i);
if(map.containsKey(ch)){ //ch为),},]的情况
if(stack.isEmpty()||stack.peek()!=map.get(ch)){
return false;
}
stack.pop();
}else{ //ch为(,{,[ 这两种情况
stack.push(ch);
}
}
return stack.isEmpty();
}
}
例题7:简化路径
class Solution {
public String simplifyPath(String path) {
//根据/进行切分
String[] strArr=path.split("/");
//使用栈进行保存
Stack<String> stack=new Stack<>();
for(int i=0;i<strArr.length;++i){
if(strArr[i].equals("..")&&!stack.isEmpty()){
stack.pop();
}else if(strArr[i].equals("..")||strArr[i].equals(".")||strArr[i].equals("")){
continue;
}else{
stack.push(strArr[i]);
}
}
//输出
List<String> myList=new ArrayList<>();
while(!stack.isEmpty()){
myList.add(stack.pop());
}
StringBuilder strB=new StringBuilder();
for(int i=myList.size()-1;i>=0;--i){
strB.append("/");
strB.append(myList.get(i));
}
return strB.length()==0?"/":strB.toString();
}
}
例题8:柱状图中最大的矩形
class Solution {
public int largestRectangleArea(int[] heights) {
int n=heights.length;
int[] left=new int[n];
int[] right=new int[n];
Stack<Integer> stack=new Stack<>();
for(int i=0;i<n;++i){
while(!stack.isEmpty()&&heights[stack.peek()]>=heights[i]){
stack.pop();
}
left[i]=stack.isEmpty()?-1:stack.peek(); //注意这里填充的是-1
stack.push(i);
}
stack.clear();
for(int i=n-1;i>=0;--i){
while(!stack.isEmpty()&&heights[stack.peek()]>=heights[i]){
stack.pop();
}
right[i]=stack.isEmpty()?n:stack.peek(); //注意这里填充的是n
stack.push(i);
}
int ans=0;
for(int i=0;i<n;++i){
ans=Math.max(ans,heights[i]*(right[i]-left[i]-1));
}
return ans;
}
}
例题9:最大矩形
class Solution {
public int maximalRectangle(char[][] matrix) {
int n=matrix.length;
if(n==0){
return 0;
}
int m=matrix[0].length;
//获得每个元素左侧连续1的个数
int[][] left=new int[n][m];
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(matrix[i][j]=='1'){
left[i][j]=(j==0?1:left[i][j-1]+1);
}
}
}
int result=0;
for(int j=0;j<m;++j){
//对于每一列使用“柱状图中最大的矩形”的单调栈方法
int[] up=new int[n];
int[] down=new int[n];
Stack<Integer> stack=new Stack<>();
for(int i=0;i<n;++i){
while(!stack.isEmpty()&&left[stack.peek()][j]>=left[i][j]){
stack.pop();
}
up[i]=stack.isEmpty()?-1:stack.peek();
stack.push(i);
}
stack.clear();
for(int i=n-1;i>=0;--i){
while(!stack.isEmpty()&&left[stack.peek()][j]>=left[i][j]){
stack.pop();
}
down[i]=stack.isEmpty()?n:stack.peek();
stack.push(i);
}
for(int i=0;i<n;++i){
int height=down[i]-up[i]-1;
int areas=height*left[i][j];
result=Math.max(result,areas);
}
}
return result;
}
}