diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index 8a8d3a52..1f245699 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -418,6 +418,112 @@ var maxSlidingWindow = function (nums, k) { }; ``` +Swift: +```Swift +/// 双向链表 +class DoublyListNode { + var head: DoublyListNode? + var tail: DoublyListNode? + var next: DoublyListNode? + var pre: DoublyListNode? + var value: Int = 0 + init(_ value: Int = 0) { + self.value = value + } + func isEmpty() -> Bool { + return self.head == nil + } + func first() -> Int? { + return self.head?.value + } + func last() -> Int? { + return self.tail?.value + } + func removeFirst() { + if isEmpty() { + return + } + let next = self.head!.next + self.head?.next = nil// 移除首节点 + next?.pre = nil + self.head = next + } + func removeLast() { + if let tail = self.tail { + if let pre = tail.pre { + self.tail?.pre = nil + pre.next = nil + self.tail = pre + } else { + self.head = nil + self.tail = nil + } + } + } + func append(_ value: Int) { + let node = DoublyListNode(value) + if self.head != nil { + node.pre = self.tail + self.tail?.next = node + self.tail = node + } else { + self.head = node + self.tail = node + self.pre = nil + self.next = nil + } + } +} +// 单调队列, 从大到小 +class MyQueue { +// var queue: [Int]!// 用数组会超时 + var queue: DoublyListNode! + init() { +// queue = [Int]() + queue = DoublyListNode() + } + // 滑动窗口时弹出第一个元素, 如果相等再弹出 + func pop(x: Int) { + if !queue.isEmpty() && front() == x { + queue.removeFirst() + } + } + // 滑动窗口时添加下一个元素, 移除队尾比 x 小的元素 始终保证队头 > 队尾 + func push(x: Int) { + while !queue.isEmpty() && queue.last()! < x { + queue.removeLast() + } + queue.append(x) + } + // 此时队头就是滑动窗口最大值 + func front() -> Int { + return queue.first() ?? -1 + } +} + +class Solution { + func maxSlidingWindow(_ nums: [Int], _ k: Int) -> [Int] { + // 存放结果 + var res = [Int]() + let queue = MyQueue() + // 先将前K个元素放入队列 + for i in 0 ..< k { + queue.push(x: nums[i]) + } + // 添加当前队列最大值到结果数组 + res.append(queue.front()) + for i in k ..< nums.count { + // 滑动窗口移除最前面元素 + queue.pop(x: nums[i - k]) + // 滑动窗口添加下一个元素 + queue.push(x: nums[i]) + // 保存当前队列最大值 + res.append(queue.front()) + } + return res + } +} +``` -----------------------