CS-Notes/notes/Leetcode 题解 - 栈和队列.md
2019-07-13 23:48:24 +08:00

232 lines
6.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- GFM-TOC -->
* [1. 用栈实现队列](#1-用栈实现队列)
* [2. 用队列实现栈](#2-用队列实现栈)
* [3. 最小值栈](#3-最小值栈)
* [4. 用栈实现括号匹配](#4-用栈实现括号匹配)
* [5. 数组中元素与下一个比它大的元素之间的距离](#5-数组中元素与下一个比它大的元素之间的距离)
* [6. 循环数组中比当前元素大的下一个元素](#6-循环数组中比当前元素大的下一个元素)
<!-- GFM-TOC -->
# 1. 用栈实现队列
[232. Implement Queue using Stacks (Easy)](https://leetcode.com/problems/implement-queue-using-stacks/description/)
栈的顺序为后进先出而队列的顺序为先进先出使用两个栈实现队列一个元素需要经过两个栈才能出队列在经过第一个栈时元素顺序被反转经过第二个栈时再次被反转此时就是先进先出顺序
```java
class MyQueue {
private Stack<Integer> in = new Stack<>();
private Stack<Integer> out = new Stack<>();
public void push(int x) {
in.push(x);
}
public int pop() {
in2out();
return out.pop();
}
public int peek() {
in2out();
return out.peek();
}
private void in2out() {
if (out.isEmpty()) {
while (!in.isEmpty()) {
out.push(in.pop());
}
}
}
public boolean empty() {
return in.isEmpty() && out.isEmpty();
}
}
```
# 2. 用队列实现栈
[225. Implement Stack using Queues (Easy)](https://leetcode.com/problems/implement-stack-using-queues/description/)
在将一个元素 x 插入队列时为了维护原来的后进先出顺序需要让 x 插入队列首部而队列的默认插入顺序是队列尾部因此在将 x 插入队列尾部之后需要让除了 x 之外的所有元素出队列再入队列
```java
class MyStack {
private Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
int cnt = queue.size();
while (cnt-- > 1) {
queue.add(queue.poll());
}
}
public int pop() {
return queue.remove();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
```
# 3. 最小值栈
[155. Min Stack (Easy)](https://leetcode.com/problems/min-stack/description/)
```java
class MinStack {
private Stack<Integer> dataStack;
private Stack<Integer> minStack;
private int min;
public MinStack() {
dataStack = new Stack<>();
minStack = new Stack<>();
min = Integer.MAX_VALUE;
}
public void push(int x) {
dataStack.add(x);
min = Math.min(min, x);
minStack.add(min);
}
public void pop() {
dataStack.pop();
minStack.pop();
min = minStack.isEmpty() ? Integer.MAX_VALUE : minStack.peek();
}
public int top() {
return dataStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
```
对于实现最小值队列问题可以先将队列使用栈来实现然后就将问题转换为最小值栈这个问题出现在 编程之美3.7
# 4. 用栈实现括号匹配
[20. Valid Parentheses (Easy)](https://leetcode.com/problems/valid-parentheses/description/)
```html
"()[]{}"
Output : true
```
```java
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
} else {
if (stack.isEmpty()) {
return false;
}
char cStack = stack.pop();
boolean b1 = c == ')' && cStack != '(';
boolean b2 = c == ']' && cStack != '[';
boolean b3 = c == '}' && cStack != '{';
if (b1 || b2 || b3) {
return false;
}
}
}
return stack.isEmpty();
}
```
# 5. 数组中元素与下一个比它大的元素之间的距离
[739. Daily Temperatures (Medium)](https://leetcode.com/problems/daily-temperatures/description/)
```html
Input: [73, 74, 75, 71, 69, 72, 76, 73]
Output: [1, 1, 4, 2, 1, 1, 0, 0]
```
在遍历数组时用栈把数组中的数存起来如果当前遍历的数比栈顶元素来的大说明栈顶元素的下一个比它大的数就是当前元素
```java
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] dist = new int[n];
Stack<Integer> indexs = new Stack<>();
for (int curIndex = 0; curIndex < n; curIndex++) {
while (!indexs.isEmpty() && temperatures[curIndex] > temperatures[indexs.peek()]) {
int preIndex = indexs.pop();
dist[preIndex] = curIndex - preIndex;
}
indexs.add(curIndex);
}
return dist;
}
```
# 6. 循环数组中比当前元素大的下一个元素
[503. Next Greater Element II (Medium)](https://leetcode.com/problems/next-greater-element-ii/description/)
```text
Input: [1,2,1]
Output: [2,-1,2]
Explanation: The first 1's next greater number is 2;
The number 2 can't find next greater number;
The second 1's next greater number needs to search circularly, which is also 2.
```
739. Daily Temperatures (Medium) 不同的是数组是循环数组并且最后要求的不是距离而是下一个元素
```java
public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
int[] next = new int[n];
Arrays.fill(next, -1);
Stack<Integer> pre = new Stack<>();
for (int i = 0; i < n * 2; i++) {
int num = nums[i % n];
while (!pre.isEmpty() && nums[pre.peek()] < num) {
next[pre.pop()] = num;
}
if (i < n){
pre.push(i);
}
}
return next;
}
```
# 微信公众号
更多精彩内容将发布在微信公众号 CyC2018 你也可以在公众号后台和我交流学习和求职相关的问题另外公众号提供了该项目的 PDF 等离线阅读版本后台回复 "下载" 即可领取公众号也提供了一份技术面试复习大纲不仅系统整理了面试知识点而且标注了各个知识点的重要程度从而帮你理清多而杂的面试知识点后台回复 "大纲" 即可领取我基本是按照这个大纲来进行复习的对我拿到了 BAT 头条等 Offer 起到很大的帮助你们完全可以和我一样根据大纲上列的知识点来进行复习就不用看很多不重要的内容也可以知道哪些内容很重要从而多安排一些复习时间
<br><div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/other/公众号海报6.png"></img></div>