首先用了暴力解法,没法通过该题,然后对暴力解法做了改进,即遍历每个滑动窗口,记录最大值和最大值所在的索引,然后遍历下一个窗口,如果新进来的那个元素大于原先的最大值,则将最大值和索引更新,如果最大值元素是原来窗口中的元素,且不是第一个,则不变,如果最大值是原来窗口第一个元素,则重新找一下最大值。这样确实时间复杂度减小,但是最差情况时间复杂度没有变化,依然通不过。 最后看了下解题思路,解决方法如下: 最关键是要知道一个规律:如果i<j,a[i]<a[j],那么a[i]便没有任何意义,可以删除掉,因为窗口中已经包含a[j]了,因此最大值永远不可能是a[i]了。 于是通过这个规律可以用下列的算法解决: 1.new一个list,用来存储现在及之后的窗口可能包含的最大值的元素。 2.遍历num list,然后将num[i]和可能最大值list[-1]去比,如果num[i]>=list[-1],也就是我们前面说的i<j,a[i]<a[j]的情况,于是可以把list[-1]删掉,在将num[i]和新的list[-1]去比,依次类推。同时还需要判断可能最大值list[0]是不是在窗口范围内了,不再的话把list[0]删掉。 3.每次更新好可能的最大值list之后第0个元素就是本窗口的最大值了。
注意:1.边界条件需注意下;2.窗口长度为1的情况单独处理下;3.可能的最大值list可以存index,而不是存具体的元素,这样方便判断可能的最大值list是否都在窗口期了。
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param num int整型一维数组
# @param size int整型
# @return int整型一维数组
#
class Solution:
def maxInWindows1(self , num, size: int):
# write code here
# 时间复杂度超上限
maxlist = []
leng = len(num) - size + 1
for i in range(leng):
maxlist.append(max(num[i : i+size]))
return maxlist
def maxInWindows2(self , num, size: int):
# 时间复杂度有所改进,但还是不够快
leng = len(num) - size + 1
tmp = num[0 : size]
maxv = max(tmp)
maxind = tmp.index(maxv)
maxlist = [maxv]
for i in range(1,leng):
tmp = num[i : i+size]
if tmp[-1] >= maxlist[-1]:
maxv = tmp[-1]
maxind = i+size-1
maxlist.append(maxv)
else:
if maxind >= i:
maxlist.append(maxv)
else:
maxv = max(tmp)
maxind = tmp.index(maxv)
maxind = maxind + i
maxlist.append(maxv)
return maxlist
def maxInWindows(self , num, size: int):
if size == 1:
return num
maxlist = []
prilist = [0]
for i in range(1,len(num)):
while len(prilist)>0 and num[i] >= num[prilist[-1]]:
prilist.pop()
prilist.append(i)
while prilist[0] < i-size+1:
del prilist[0]
if i >= size-1:
maxlist.append(num[prilist[0]])
return maxlist
num = [2,3,4,2,6,2,5,1]
size = 3
print(Solution().maxInWindows(num , size))