Day 10 总结
- 自己实现中遇到哪些困难
- 失误还是很多,没有考虑完全一些特殊情况和边界情况
- 今日收获,记录一下自己的学习时间
- 16:30 - 18:00
- 解惑(补充)
理论基础
- 栈和队列属于容器,内部使用其他数据结构实现,提供特定操作
- 栈:先进后出
- 队列:先进先出
- Java 栈
-
Stack<Integer> stack = new Stack<>(); push pop peek isEmpty
-
- Java 队列
- 普通队列 (LinkedList)
-
Queue<Integer> queue = new LinkedList<>(); offer / add poll peek isEmpty - 优先级队列 (PriorityQueue)
-
// 默认小顶堆 PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(); // 创建大顶堆 PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(Comparator.reverseOrder()); // 定义元素 Comparator<Map.Entry<Integer, Integer>> myComparator = new Comparator<>() { @Override public int compare( Map.Entry<Integer,Integer> e1, Map.Entry<Integer,Integer> e2) { return e1.getValue() - e2.getValue(); // return Integer.compare(int1, int2); } }; PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>(myComparator); // Lambda表达式写法 Comparator<Task> priorityComparator = (task1, task2) -> task2.priority - task1.priority; - 双端队列 (ArrayDeque)
-
// ArrayDeque可以作为栈和双端队列使用 Deque<Integer> stack = new ArrayDeque<>(); Deque<Integer> deque = new ArrayDeque<>(); Deque<Integer> deque = new LinkedListL<>(); addFirst addLast removeFirst peekFirst() - Map 与 优先级队列
-
// Map Map<Integer, Integer> map = new HashMap<>(); Map.Entry<Integer, Integer> map.entrySet() map.containsKey() map.keySet() map.values() // Comparator Comparator<Map.Entry<Integer, Integer>> myComparator = new Comparator<>() { @Override public int compare(Map.Entry<Integer,Integer> e1, Map.Entry<Integer,Integer> e2) { return e1.getValue() - e2.getValue(); } }; // PQ PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>(myComparator); pq.poll() pq.add()
- 栈与队列的内部实现机制
文章讲解:代码随想录
232.用栈实现队列 (简单)
题目链接/文章讲解/视频讲解:代码随想录
题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/description/
实现思路:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x)将元素 x 推到队列的末尾int pop()从队列的开头移除并返回元素int peek()返回队列开头的元素boolean empty()如果队列为空,返回true;否则,返回false
两个栈实现队列:当元素压入队列当中时,把输出栈元素倒入输入栈,再把元素压入输入栈中;当需要抛出元素时,把输入栈中的元素倒入到输出栈中,再从输出栈中抛出元素;
代码实现:
class MyQueue {
Stack<Integer> in;
Stack<Integer> out;
public MyQueue() {
in = new Stack<>();
out = new Stack<>();
}
public void push(int x) {
while (!out.isEmpty()) in.push(out.pop()); // 该步骤可省略
in.push(x);
}
public int pop() {
while (!in.isEmpty()) out.push(in.pop());
return out.pop();
}
public int peek() {
while (!in.isEmpty()) out.push(in.pop());
return out.peek();
}
public boolean empty() {
return in.isEmpty() && out.isEmpty();
}
}
225. 用队列实现栈 (简单)
建议大家掌握一个队列的方法,更简单一些,可以先看视频讲解
题目链接/文章讲解/视频讲解:代码随想录
题目链接:https://leetcode.cn/problems/implement-stack-using-queues/description/
实现思路:
使用一个队列实现栈:压入元素的时候按序压入,抛出元素的时候,遍历整个队列,找到最后一个压入的元素,抛出。遍历过程中再将元素重新压入到队列尾部。可以通过size变量进行计数,也可以通过比较目前队列头部元素否为最开始时的队首元素,判断是否抛出的是最后一个元素。
我的失误:
实现 pop 的时候没有考虑特殊情况当队列内只有一个元素时,即队首元素就是队尾元素。
代码实现:
public void push(int x) {
queue.add(x);
}
public int pop() {
Integer first = queue.poll();
if (queue.isEmpty()) return first;
Integer result = first;
while (queue.peek() != first) {
queue.add(result);
result = queue.poll();
}
return result;
}
// 通过size变量实现计数
public int pop() {
int size = queue.size();
while (size-- > 1)
queue.add(queue.poll());
return queue.poll();
}
public int top() {
Integer result = pop();
queue.add(result);
return result;
}
卡哥的思路是压入的时候就进行排序,把刚压入的元素直接放在队首,方便抛出操作。
//每 offer 一个数(A)进来,都重新排列,把这个数(A)放到队列的队首
public void push(int x) {
queue.offer(x);
int size = queue.size();
//移动除了 A 的其它数
while (size-- > 1)
queue.offer(queue.poll());
}
public int pop() {
return queue.poll();
}
public int top() {
return queue.peek();
}
20. 有效的括号 (简单)
题目链接/文章讲解/视频讲解:代码随想录
题目链接:https://leetcode.cn/problems/valid-parentheses/description/
实现思路:
括号一定是成对出现,出现右边括号的时候一定能消除掉一个左括号,如果出现了左括号不匹配右括号的情况,说明出现不成对的括号。通过栈结构存储左括号,匹配出现的右括号进行消除。
我的失误:
忽略了栈空时不能 peek,忽略了如果结束了之后栈不为空说明还有未匹配的括号。
代码实现:
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
char[] arr = s.toCharArray();
for (int i=0; i<arr.length; i++) {
if (arr[i] == '{' || arr[i] == '(' || arr[i] == '[')
stack.push(arr[i]);
else {
if (stack.isEmpty()) return false;
if (arr[i] == '}') {
if (stack.peek() == '{') stack.pop();
else return false;
}
else if (arr[i] == ')') {
if (stack.peek() == '(') stack.pop();
else return false;
}
else if (arr[i] == ']') {
if (stack.peek() == '[') stack.pop();
else return false;
}
}
}
return stack.isEmpty();
}
1047. 删除字符串中的所有相邻重复项 (简单)
题目链接/文章讲解/视频讲解:代码随想录
题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/
实现思路:
给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们。在 s 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
同上题一样,匹配左右括号变成匹配相同字符。再把栈中字符组成字符串。
代码实现:
public String removeDuplicates(String s) {
Stack<Character> stack = new Stack<>();
char[] arr = s.toCharArray();
for (int i=0; i<arr.length; i++) {
char c = arr[i];
if (!stack.isEmpty() && c == stack.peek())
stack.pop();
else stack.push(c);
}
arr = new char[stack.size()];
for (int i=stack.size()-1; i>=0; i--)
arr[i] = stack.pop();
return new String(arr);
}

606

被折叠的 条评论
为什么被折叠?



