题目1: 150. 逆波兰表达式求值
// @lc code=start
class Solution {
func evalRPN(_ tokens: [String]) -> Int {
var stack = [Int]()
let operation = ["+", "-", "*", "/"]
for token in tokens {
if !operation.contains(token) {
stack.append(Int(token)!)
continue
}
let lastEl = stack.popLast()!
let otherEl = stack.popLast()!
switch token {
case "+":
stack.append(otherEl + lastEl)
case "-":
stack.append(otherEl - lastEl)
case "*":
stack.append(otherEl * lastEl)
case "/":
stack.append(Int(otherEl / lastEl))
default: break
}
}
return stack.first!
}
}
// @lc code=end
题目2: 239. 滑动窗口最大值
思路基本上理解了
用单调队列存值,取队尾元素为窗口最大值。 不断的入队 出队、然后每次都取队尾元素为当前窗口最大值。
如何获得这个单调队列?
首先这里需要一个双端队列deque,队首入队,队尾出队。
其次需要完成下面几个规则:
- push: 入队操作,循环队列, 如果队列非空,并且队首 小于入队元素, 那么移除队首元素。 这样保持队列的单调性
- pop: 出队操作,只有当出队元素等于队尾元素时,队尾元素pop,否则不操作。 解释一下:因为push操作导致队列元素只会小于或者等于 窗口长度,所以这里出队的时候有可能已经被提前移除了。
- 获取最大值: 享受成果,直接拿队尾元素即可。
class Solution {
func maxSlidingWindow(_ nums: [Int], _ k: Int) -> [Int] {
// 单调队列,从大到小
var queue = [Int]()
func push(_ val: Int) {
while !queue.isEmpty, queue.last! < val {
queue.removeLast()
}
queue.append(val)
}
func pop(_ val: Int) {
if !queue.isEmpty, queue.first! == val {
queue.removeFirst()
}
}
func getMax() -> Int {
queue.first ?? -1
}
var res = [Int]()
for i in 0..<k {
push(nums[i])
}
res.append(getMax())
for i in k..<nums.count {
push(nums[i])
pop(nums[i - k])
res.append(getMax())
}
return res
}
}
题目3: 347.前 K 个高频元素
这个题目的重点应该集中在大顶堆 小顶堆的实现上。 了解这个具体的实现,整个算法思路就清晰了。