1.青铜挑战——滑动窗口其实很简单
本章研究双指针和滑动窗口思想,在一维数组和链表部分我们已经介绍了很多双指针的题目,滑动窗口其实是其进一步拓展。
1.滑动窗口基本思想
所谓窗口就是建立两个索引,left和right,并且保持right-left=3,然后一遍遍历序列,一边寻找,每改变一次就标记一下当前区间的最大值就行了。
窗口:窗口其实就是两个变量left和right之间的元素,也可以理解为一个区间,窗口大小可能固定,也可能变化,如果是固定大小的,那么自然要先确定窗口是否越界,再执行逻辑处理。如果不是固定的,就要先判断是否满足要求,再执行逻辑处理
滑动:说明这个窗口是移动的,事实上移动的仍然是left和right两个变量,而不是序列中的元素。当变量移动是,其中见的元素必然会发生变化,因此就有了这种不断滑动的效果。
在实际问题中,窗口大小不一定是固定的,我们呢可以思考两种场景:
1.固定窗口的滑动就是火车行驶这种大小不变的移动
2.可变的窗口就像两个老师带着一队学生外出,一个负责开路,一个负责断后,中间则是小朋友。两位老师之间的距离可能有时大有时小,但是整体窗口是不断滑动的。
根据窗口大小是否固定,可以造出两种类型的题。
1.如果是固定的,则一般会让你求那个窗口的元素最大最小平均值和最大最小等等类型的问题。2.如果窗口是变的,则一般会让你求一个序列里最大,最小窗口是什么等等
2.两个入门题
2.1.子数组最大平均数
LeetCode643:给定n个整数,找出平均数最大且长度为K的连续子数组,并输出该最大平均数
第一步:先求第一个窗口的和
第二步:遍历,每次右边增加一个,左边减去一个,重新计算窗口最大值
class Solution:
def findMaxAverage(self, nums, k):
low = 0
all = sum(nums[0:k])
avg = all
for i in range(k, len(nums)):
all = all + nums[i] - nums[low]
low += 1
avg = max(avg, all)
return avg/k
if __name__ == "__main__":
nums = [1, 12, -5, -6, 50, 3]
k = 4
findMaxAverage = Solution()
print(findMaxAverage.findMaxAverage(nums, k))
2.2最长连续递增序列
(一个窗户变化的情况)LeetCode674:给定一个未经排序的整数数组,找到最长且连续递增的子序列,并返回该序列的长度。
class Solution:
def findLengthOfLCIS(self, nums):
ans = 0
n = len(nums)
start = 0
for i in range(n):
if i > 0 and nums[i - 1] >= nums[i]:
start = i
ans = max(ans, i - start + 1)
return ans
def findLengthOfLCIS2(self, nums):
cur_len = 1
res = 1
for i in range(len(nums)):
if nums[i] < nums[i - 1]:
cur_len = 1
else:
cur_len += 1
res = max(res, cur_len)
return res
if __name__ == "__main__":
nums = [1, 3, 5, 4, 7, 8, 9, 2]
findLengthOfLCIS = Solution()
print(findLengthOfLCIS.findLengthOfLCIS(nums))