算法 - 栈与队列02 (Swift版本)

77 阅读1分钟

题目1: 150. 逆波兰表达式求值

题目&讲解
leetcode

// @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. 滑动窗口最大值

题目&讲解
leetcode

思路基本上理解了
用单调队列存值,取队尾元素为窗口最大值。  不断的入队 出队、然后每次都取队尾元素为当前窗口最大值。
如何获得这个单调队列?
首先这里需要一个双端队列deque,队首入队,队尾出队。
其次需要完成下面几个规则:

  1. push: 入队操作,循环队列, 如果队列非空,并且队首 小于入队元素, 那么移除队首元素。  这样保持队列的单调性
  2. pop: 出队操作,只有当出队元素等于队尾元素时,队尾元素pop,否则不操作。  解释一下:因为push操作导致队列元素只会小于或者等于 窗口长度,所以这里出队的时候有可能已经被提前移除了。
  3. 获取最大值: 享受成果,直接拿队尾元素即可。
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 个高频元素

题目&讲解
leetcode

这个题目的重点应该集中在大顶堆 小顶堆的实现上。 了解这个具体的实现,整个算法思路就清晰了。