Stack

1
2
3
4
5
6
7
8
9
10
// 初始化
Stack<E> stack = new Stack<>();
// 入栈
stack.push(E item);
// 弹出
stack.pop();
// 查看栈顶元素
stack.peek();
// 判空
stack.empty();

Queue

1
2
3
4
5
6
7
8
9
10
// 初始化
Queue<E> queue = new LinkedList<>();
// 入队列
queue.offer();
// 弹出
queue.poll();
// 查看队头元素
queue.peek();
// 判空
queue.isEmpty();

20. 有效的括号

20. 有效的括号 - 力扣(LeetCode)

Snipaste_2024-09-12_15-09-55

解题思路:从左向右遍历,遇到左括号入栈,遇到与栈顶元素匹配的右括号将栈顶弹出。否则不匹配或最后栈内不为空说明无效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
continue;
} else if (stack.isEmpty()) return false;
if (c == ')' && stack.peek() == '(') stack.pop();
else if (c == '}' && stack.peek() == '{') stack.pop();
else if (c == ']' && stack.peek() == '[') stack.pop();
else return false;
}
if (!stack.isEmpty()) return false;
return true;
}
}

239. 滑动窗口最大值

239. 滑动窗口最大值 - 力扣(LeetCode)

image-20240912182033855 image-20240912182116876

暴力方法:每次从窗口中找出最大值,时间复杂度是O(n x k)

解决思路:利用队列,队列里面维护可能成为窗口最大值的元素,同时保证队列中的元素是从大到小的,即单调队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//解法一
//自定义数组
class MyQueue {
Deque<Integer> deque = new LinkedList<>();
//弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
//同时判断队列当前是否为空
void poll(int val) {
if (!deque.isEmpty() && val == deque.peek()) {
deque.poll();
}
}
//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
//保证队列元素单调递减
//比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
void add(int val) {
while (!deque.isEmpty() && val > deque.getLast()) {
deque.removeLast();
}
deque.add(val);
}
//队列队顶元素始终为最大值
int peek() {
return deque.peek();
}
}

class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 1) {
return nums;
}
int len = nums.length - k + 1;
//存放结果元素的数组
int[] res = new int[len];
int num = 0;
//自定义队列
MyQueue myQueue = new MyQueue();
//先将前k的元素放入队列
for (int i = 0; i < k; i++) {
myQueue.add(nums[i]);
}
res[num++] = myQueue.peek();
for (int i = k; i < nums.length; i++) {
//滑动窗口移除最前面的元素,移除是判断该元素是否放入队列
myQueue.poll(nums[i - k]);
//滑动窗口加入最后面的元素
myQueue.add(nums[i]);
//记录对应的最大值
res[num++] = myQueue.peek();
}
return res;
}
}

347.前 K 个高频元素

347. 前 K 个高频元素 - 力扣(LeetCode)

image-20240912190035530

解题思路:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
int[] ans = new int[k];
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
List<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(map.entrySet());

// 按照 Entry 的 value 进行排序,降序
entryList.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));
for (int i = 0; i < k; i++) {
ans[i] = entryList.get(i).getKey();
}
return ans;
}
}