『代码随想录』栈与队列(Stack & Queue)
DAY 10
232.用栈实现队列
因为栈和队列的出队顺序是反的,所以再来个栈倒腾一下就是正的了
1 | type MyQueue struct { |
225.用队列实现栈
一个队列就够了
出栈的话,把前 n-1
个元素扔到后面去(我称之为 shift
操作),当前元素就是刚入队的元素了
Top
的话就先出栈再放进去
1 | type MyStack struct { |
也可以换个思路,在 Push
的时候就 shift
也行,看上去更简单
1 | type MyStack struct { |
DAY 11
20.有效的括号
经典的栈应用
1 | func isValid(s string) bool { |
1047.删除字符串中的所有相邻重复项
1 | func removeDuplicates(s string) string { |
150.逆波兰表达式求值
经典中的经典
1 | func evalRPN(tokens []string) int { |
DAY 12
周日休息
DAY 13
239.滑动窗口最大值
非常好的单调队列例题
单调队列,队列中从头到尾单调递减
- Pop:传入当前窗口移动需要弹出的值,如果等于头元素则弹出
- Push:在尾部尝试加入,如果遇到比当前元素小的都从尾部弹出
- GetMax:取头元素
1 | type MonoQ struct { |
347.前 K 个高频元素
两种方法,拿到频率的 map 之后用堆维护前 K 个,或者直接排序再取前 K 个
复习一下 Golang 里面的优先队列和排序
用惯了 C++ STL 的开箱即用的优先队列,我只能说 Golang 的优先队列真的不好用(
-
排序,记得导入
sort
包使用内建的
Ints
1
2nums := []int{4, 2, 3, 1}
sort.Ints(nums)使用
sort.Slice
1
2
3sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age
}) -
优先队列,记得导入
heap
包需要实现几个接口,在使用的时候,如果你是直接将一个切片转换成堆,需要使用
heap.Init
需要注意的是使用的时候不是面向对象的,你需要使用
heap.XX
来操作元素仅为
int
的简单队列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
32type IntPriorityQueue []int
func (pq IntPriorityQueue) Len() int { return len(pq) }
func (pq IntPriorityQueue) Less(i, j int) bool { return pq[i] < pq[j] }
func (pq IntPriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] }
func (pq *IntPriorityQueue) Push(x interface{}) {
*pq = append(*pq, x.(int))
}
func (pq *IntPriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
*pq = old[0 : n-1]
return item
}
func main() {
pq := &IntPriorityQueue{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}
// 建立优先队列堆
heap.Init(pq)
// 向优先队列中添加元素
heap.Push(pq, 7)
// 从优先队列中按照优先级取出元素
for pq.Len() > 0 {
fmt.Printf("%d ", heap.Pop(pq))
}
}根据结构体中的一个字段进行排序的队列
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// Item 表示优先队列中的元素
type Item struct {
value interface{} // 元素的值
priority int // 优先级
}
// PriorityQueue 实现了heap.Interface接口
type PriorityQueue []Item
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
// 这里我们使用优先级来决定元素的顺序,较小的优先级排在前面
return pq[i].priority < pq[j].priority
}
func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
}
func (pq *PriorityQueue) Push(x interface{}) {
item := x.(Item)
*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
*pq = old[0 : n-1]
return item
}
func main() {
// 创建一个优先队列
pq := make(PriorityQueue, 0)
// 添加元素到优先队列
heap.Push(&pq, Item{value: "B", priority: 2})
heap.Push(&pq, Item{value: "C", priority: 1})
heap.Push(&pq, Item{value: "A", priority: 3})
// 从优先队列中按照优先级取出元素
for pq.Len() > 0 {
item := heap.Pop(&pq).(Item)
fmt.Printf("%s (priority: %d)\n", item.value, item.priority)
}
}
言归正传,本体的两种方法
-
直接排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23func topKFrequent(nums []int, k int) []int {
m := make(map[int]int)
for _, v := range nums {
m[v]++
}
count := make([][2]int, 0, len(m))
for k, v := range m {
count = append(count, [2]int{k, v})
}
sort.Slice(count, func(i, j int) bool {
return count[i][1] > count[j][1]
})
ans := make([]int, 0, k)
for i := 0; i < k; i++ {
ans = append(ans, count[i][0])
}
return ans
}还可以更简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17func topKFrequent(nums []int, k int) []int {
m := make(map[int]int)
for _, v := range nums {
m[v]++
}
ans := make([]int, 0, len(m))
for k, _ := range m {
ans = append(ans, k)
}
sort.Slice(ans, func(i, j int) bool {
return m[ans[i]] > m[ans[j]]
})
return ans[: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
45type Item struct {
value int
freq int
}
type PriorityQueue []Item
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool { return pq[i].freq < pq[j].freq }
func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] }
func (pq *PriorityQueue) Push(x interface{}) {
item := x.(Item)
*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
*pq = old[0 : n-1]
return item
}
func topKFrequent(nums []int, k int) []int {
m := make(map[int]int)
for _, num := range nums {
m[num]++
}
pq := make(PriorityQueue, 0)
for value, freq := range m {
heap.Push(&pq, Item{value, freq})
if pq.Len() > k {
heap.Pop(&pq)
}
}
ans := make([]int, k)
for i := 0; i < k; i++ {
item := heap.Pop(&pq).(Item)
ans[i] = item.value
}
return ans
}
评论
GiscusTwikoo