Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions Archer/239. Sliding Window Maximum/239. Sliding Window Maximum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-


# 方法一、利用队列的思想,先进先出,不断滑动窗口[i:i+k]
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""

win = []
n = len(nums)

if nums != []:
for i in range(n - k + 1):
win.append(max(nums[i:i + k]))

return win

# 利用hea实现队列操作,先进先出
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
import heapq

win = []
hea = []# 注意不能写成:win = hea = []

n = len(nums)

hea.append(0)

for num in nums[0:k - 1]:
hea.append(num)

if nums != []:
for i in range(k - 1, n):
hea.append(nums[i])
hea.pop(0)
win.append(max(hea))

return win
# 方法三、利用双向队列(效率最高)
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
win = []
hea = []

n = len(nums)

for i in range(k - 1): # 先建立第一个窗口的前k-1个
while hea != [] and nums[hea[-1]] < nums[i]: # 一直比较新数及队尾元素,若队尾较小则出队
hea.pop()
hea.append(i) #新数的索引入队

if nums != []:
for i in range(k - 1, n):
if hea != [] and (i - hea[0]) == k: # 队列中最大值的索引与新数的索引如果溢出窗口k,则队头出队
hea.pop(0)
while hea != [] and nums[hea[-1]] < nums[i]:
hea.pop()
hea.append(i)
win.append(nums[hea[0]]) # 队头的索引指示该窗口下的最大值

return win

# 方法四、利用堆思想,跟方法三雷同

class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
import heapq # 需要这个模块建立堆

win = []
hea = []

n = len(nums)

for i in range(n):
while hea != [] and (i - hea[0][1]) > k - 1: # 如果堆顶点对应的索引溢出,删除堆顶点(即删除最大值)
heapq.heappop(hea)
heapq.heappush(hea, (-nums[i], i)) #同时将数值和索引输入堆,以便判断堆顶点的索引是否溢出
if i > k - 2: # 在堆至少为窗口大小时,才开始输出最大值
win.append(-hea[0][0])

return win
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 算法实现:(详细见代码文档) #

#给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。返回滑动窗口最大值。 #

# 复盘 #

1. 用索引i和j不断滑动数组:nums[i:j],然后max求最大值

2. 用伪队列思想,设置一个队列,然后不断入队出队,然后求最大值
3. 双向队列,比较巧妙,队列里存储的是索引,具体解析见代码文档(注意的是,因为一边比较一边出队,比最大值更前的索引已经出队了,所以索引溢出窗口时队头出队即可,)
4. 用堆,跟双向队列的方法雷同(注意的是,与双向队列不同,因为堆就算溢出也没有出队,所以堆要同时保存索引和值,循环判断索引溢出窗口,将堆顶弹出)
2 changes: 2 additions & 0 deletions Archer/readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
##1220-1222 打卡##
**239. Sliding Window Maximum**
##1217-1219 打卡##
**编写一个算法来判断一个数是不是“快乐数”。一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。**

Expand Down