6、栈与队列
1、用栈实现队列
public class MyQueue {
private Stack<Integer> stack1; // 用来添加元素
private Stack<Integer> stack2; // 用来缓存部分已经排好的元素
private int front; // 需要保证 front 是 stack1 中最先进来的元素
public MyQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void push(int x) {
if (stack1.isEmpty()) front = x;
stack1.push(x);
}
// [123 -> 123]
public int pop() {
if (!stack2.isEmpty()) return stack2.pop();
while (stack1.size() != 1) stack2.push(stack1.pop());
return stack1.pop();
}
public int peek() {
if (!stack2.isEmpty()) return stack2.peek();
return front;
}
public boolean empty() {
return stack1.isEmpty() && stack2.isEmpty();
}
}
2、用队列实现栈
public class MyStack {
private Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
// 3214 -> 4321
public void push(int x) {
queue.add(x);
for (int i = 0; i < queue.size() - 1; i++) queue.add(queue.remove());
}
public int pop() {
return queue.remove();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
3、有效的括号
public boolean isValid(String s) {
char[] arr = s.toCharArray();
Deque<Character> stack = new ArrayDeque<>();
for (char c : arr) {
if (c == '(' || c == '[' || c == '{') stack.addLast(c);
else {
if (stack.isEmpty()) return false;
char top = stack.removeLast();
if (top == '(' && c != ')') return false;
if (top == '[' && c != ']') return false;
if (top == '{' && c != '}') return false;
}
}
return stack.isEmpty();
}
4、删除字符串中的所有相邻重复项
public String removeDuplicates(String s) {
Deque<Character> deque = new LinkedList<>();
char[] arr = s.toCharArray();
for (char c : arr) {
if (deque.isEmpty()) deque.addLast(c);
else {
if (c != deque.getLast()) deque.addLast(c);
else deque.removeLast();
}
}
StringBuilder sb = new StringBuilder();
while (!deque.isEmpty()) sb.append(deque.removeFirst());
return sb.toString();
}
5、逆波兰表达式求值
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new ArrayDeque<>();
for (String token : tokens) {
if (!isFh(token)) stack.addLast(Integer.valueOf(token));
else {
int v2 = stack.removeLast();
int v1 = stack.removeLast();
switch (token) {
case "+":
stack.addLast(v1 + v2);
break;
case "-":
stack.addLast(v1 - v2);
break;
case "*":
stack.addLast(v1 * v2);
break;
case "/":
stack.addLast(v1 / v2);
break;
}
}
}
return stack.removeLast();
}
private boolean isFh(String str) {
return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/");
}
6、滑动窗口最大值
public static int[] maxSlidingWindow(int[] nums, int k) {
if (k == 1) return nums;
if (k >= nums.length) {
int max = nums[0];
for (int i = 1; i < nums.length; i++) max = Math.max(max, nums[i]);
return new int[]{max};
}
int[] res = new int[nums.length - k + 1];
int index = 0;
// 从大到小的单调队列, 存储的是索引
// 窗口缩小时, 队首的值会依次成为窗口内的最大值
// 新元素 cur 入队时, 队尾中值 <= cur 值需要依次弹出
Deque<Integer> deque = new LinkedList<>();
for (int r = 0; r < nums.length; r++) {
int cur = nums[r];
while (!deque.isEmpty() && nums[deque.getLast()] <= cur) deque.removeLast();
deque.addLast(r);
if (deque.getFirst() < r - k + 1) deque.removeFirst();
if (r >= k - 1) res[index++] = nums[deque.getFirst()];
}
return res;
}
7、前 K 个高频元素
public class Solution {
private class Node {
public int num;
public int count;
public Node(int num, int count) {
this.num = num;
this.count = count;
}
}
public int[] topKFrequent(int[] nums, int k) {
// 值 : 次数
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
// 根据次数来比较的最大堆
PriorityQueue<Node> maxHeap = new PriorityQueue<>((o1, o2) -> o2.count - o1.count);
map.forEach((num, count) -> maxHeap.add(new Node(num, count)));
int[] res = new int[k];
for (int i = 0; i < k; i++) {
res[i] = maxHeap.remove().num;
}
return res;
}
}
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17440651.html