# 堆的相关题目—滑动窗口

## 1、数据流滑动窗口平均值

### 样例

MovingAverage m = new MovingAverage(3);
m.next(1) = 1 // 返回 1.00000
m.next(10) = (1 + 10) / 2 // 返回 5.50000
m.next(3) = (1 + 10 + 3) / 3 // 返回 4.66667
m.next(5) = (10 + 3 + 5) / 3 // 返回 6.00000来源：https://www.lintcode.com/problem/moving-average-from-data-stream/description
from collections import deque
class MovingAverage:
def __init__(self, size):
self.queue = deque()
self.size = size
self.sum = 0.0

def next(self, val):
if  self.size == len( self.queue):
temp = self.queue.popleft()
self.sum -= temp
self.queue.append(val)
self.sum += val

return self.sum/len(self.queue)


## 2、数据流的中位数

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

findMedian() -> 1.5
findMedian() -> 2

import heapq
class MedianFinder(object):

def __init__(self):
"""
initialize your data structure here.
"""
self.minheap = []
self.maxheap = []
self.median = 0.0

"""
:type num: int
:rtype: None
"""

if len(self.maxheap) <= len(self.minheap):
heapq.heappush(self.maxheap, -num)
else:
heapq.heappush(self.minheap, num)

if len(self.minheap) == 0 or len(self.maxheap) ==0:
# print(num, self.maxheap, self.minheap)
return

if -self.maxheap[0] > self.minheap[0]:
heapq.heappush(self.maxheap, -heapq.heappop(self.minheap))
heapq.heappush(self.minheap, -heapq.heappop(self.maxheap))
# print(num, self.maxheap, self.minheap)

def findMedian(self):
"""
:rtype: float
"""
if len(self.maxheap) > len(self.minheap):
return -self.maxheap[0]
elif len(self.maxheap) < len(self.minheap):
return self.minheap[0]
else:
return float(self.minheap[0] - self.maxheap[0])/2


## 3、滑动窗口最大值

--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
# 单调双边队列
if not nums or not k :
return []

def push(queue, nums, i):
while queue and nums[i] > nums[queue[-1]]:
queue.pop()
queue.append(i)

from collections import deque
res = []
queue = deque()
for i in range(k-1):
push(queue, nums, i)

for i in range(k-1, len(nums)):
push(queue, nums, i)
res.append(nums[queue[0]])
if k == i-queue[0]+1:
queue.popleft()

return res


## 5、滑动窗口矩阵的最大值

• sum[i][j]存储左上角坐标为(0,0),右下角坐标为(i,j)的子矩阵的和。
• sum[i][j] = matrix[i - 1][j - 1] + \sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1]递推求值即可，两部分相加，减去重复计算部分。
• value = sum[i][j] - sum[i - k][j] - \sum[i][j - k] + sum[i - k][j - k]可求得一个k * k大小子矩阵的和

## 6、数据流中第一个唯一的数字

### 描述

输入：
[1, 2, 2, 1, 3, 4, 4, 5, 6]
5



输入：
[1, 2, 2, 1, 3, 4, 4, 5, 6]
7



输入：
[1, 2, 2, 1, 3, 4]
3

class Solution:
"""
@param nums: a continuous stream of numbers
@param number: a number
@return: returns the first unique number
"""
def firstUniqueNumber(self, nums, number):
# Write your code here
maps = {}
for i in nums:
maps[i] = maps.get(i, 0) + 1
if i == number:
break
else:
return -1

for i in nums:
if maps[i] == 1:
return i
if i == number:
break

return -1


(0)
(0)

© 2014 mamicode.com 版权所有 京ICP备13008772号-2