数据结构与算法-单调栈
单调栈经典题目
- 单调递增栈(栈顶元素递增):适用于找 左/右边第一个比当前值小的元素
- 单调递减栈(栈顶元素递减):适用于找 左/右边第一个比当前值大的元素
单调递减栈
496. 下一个更大元素 I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func nextGreaterElement(nums1 []int, nums2 []int) []int {
res := make([]int, len(nums1))
nextGreater := make(map[int]int)
var stack []int
for _, num := range nums2 {
for len(stack) > 0 && num > stack[len(stack)-1] {
nextGreater[stack[len(stack)-1]] = num
stack = stack[:len(stack)-1]
}
stack = append(stack, num)
}
for i, num := range nums1 {
if val, ok := nextGreater[num]; ok {
res[i] = val
} else {
res[i] = -1
}
}
return res
}
503. 下一个更大元素 II
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func nextGreaterElements(nums []int) []int {
n := len(nums)
res := make([]int, n)
for i := range res {
res[i] = -1
}
var stack []int
for i := 0; i < 2*n; i++ {
num := nums[i%n]
for len(stack) > 0 && num > nums[stack[len(stack)-1]] {
res[stack[len(stack)-1]] = num
stack = stack[:len(stack)-1]
}
if i < n {
stack = append(stack, i)
}
}
return res
}
739. 每日温度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func dailyTemperatures(temperatures []int) []int {
n := len(temperatures)
res := make([]int, n)
var stack []int
for i := 0; i < n; i++ {
for len(stack) > 0 && temperatures[i] > temperatures[stack[len(stack)-1]] {
pre := stack[len(stack)-1]
stack = stack[:len(stack)-1]
res[pre] = i - pre
}
stack = append(stack, i)
}
return res
}
901. 股票价格跨度
1
write your code here
316. 去除重复字母
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
func removeDuplicateLetters(s string) string {
last := make(map[rune]int)
for i, c := range s {
last[c] = i
}
var stack []rune
inStack := make(map[rune]bool)
for i, c := range s {
if inStack[c] {
continue
}
for len(stack) > 0 && c < stack[len(stack)-1] && last[stack[len(stack)-1]] > i {
inStack[stack[len(stack)-1]] = false
stack = stack[:len(stack)-1]
}
stack = append(stack, c)
inStack[c] = true
}
return string(stack)
}
402. 移掉 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
func removeKdigits(num string, k int) string {
var stack []byte
for i := 0; i < len(num); i++ {
// 当栈不为空,且当前数字小于栈顶数字,并且还有可以移除的数字
for k > 0 && len(stack) > 0 && stack[len(stack)-1] > num[i] {
stack = stack[:len(stack)-1] // 弹出栈顶元素
k--
}
stack = append(stack, num[i]) // 将当前数字推入栈中
}
// 如果还有剩余的 k,移除栈末尾的元素
for k > 0 {
stack = stack[:len(stack)-1]
k--
}
// 将栈中的数字拼接成字符串
res := string(stack)
// 去掉前导零
for len(res) > 0 && res[0] == '0' {
res = res[1:]
}
// 如果结果为空,返回 "0"
if res == "" {
return "0"
}
return res
}
581. 最短无序连续子数组
1
write your code here
456. 132 模式
1
write your code here
单调递增栈
907. 子数组的最小值之和
1
write your code here
42. 接雨水
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
func trap(height []int) int {
if len(height) <= 0 {
return 0
}
left, right := 0, len(height)-1
leftMax, rightMax := height[left], height[right]
res := 0
for left < right {
if height[left] < height[right] {
if height[left] < leftMax {
res += leftMax - height[left]
} else {
leftMax = height[left]
}
left++
} else {
if height[right] < rightMax {
res += rightMax - height[right]
} else {
rightMax = height[right]
}
right--
}
}
return res
}
CC BY-NC-SA 4.0
许可协议,转载请注明出处!
本博客所有文章除特别声明外,均采用