数据结构与算法之 leetcode 数组滑动窗口 最大值 / 和为 K

数据结构与算法阿木 发布于 3 天前 2 次阅读


数组滑动窗口:LeetCode中的最大值与和为K问题解析与代码实现

在LeetCode等编程竞赛和面试中,数组滑动窗口问题是一个常见的题型。这类问题通常要求我们在一个数组中滑动一个窗口,对窗口内的元素进行操作,如求最大值、求和等。本文将围绕数组滑动窗口这一主题,深入探讨LeetCode中的两个经典问题:最大值滑动窗口和和为K的滑动窗口,并给出相应的代码实现。

最大值滑动窗口

问题描述

给定一个数组和一个整数k,找出数组中长度为k的连续子数组中的最大值。

示例

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3

输出:[3,3,5,5,6,7]

解题思路

我们可以使用双端队列(deque)来实现最大值滑动窗口。双端队列允许我们在两端进行插入和删除操作,非常适合用于实现滑动窗口。

具体步骤如下:

1. 初始化一个双端队列,用于存储窗口中的最大值。

2. 遍历数组,对于每个元素:

- 将窗口中比当前元素小的值移除。

- 将当前元素加入队列。

- 如果队列的头部元素不在窗口内,将其移除。

- 将队列的头部元素(即当前窗口的最大值)加入结果列表。

代码实现

python

def maxSlidingWindow(nums, k):


if not nums or k <= 0:


return []



deque = []


result = []



for i in range(len(nums)):


移除窗口中比当前元素小的值


while deque and deque[-1] < nums[i]:


deque.pop()



将当前元素加入队列


deque.append(nums[i])



如果队列的头部元素不在窗口内,将其移除


if deque[0] == nums[i - k]:


deque.pop(0)



如果窗口已满,将队列的头部元素加入结果列表


if i >= k - 1:


result.append(deque[0])



return result


和为K的滑动窗口

问题描述

给定一个数组和一个整数k,找出数组中长度为k的连续子数组的和为k的所有子数组。

示例

输入:nums = [1,1,1], k = 3

输出:[1,1,1]

解题思路

我们可以使用哈希表来实现和为K的滑动窗口。哈希表可以快速查找和更新窗口的和。

具体步骤如下:

1. 初始化一个哈希表,用于存储窗口的和及其对应的索引。

2. 遍历数组,对于每个元素:

- 将当前元素加入窗口的和。

- 如果窗口的和等于k,将当前窗口的索引加入结果列表。

- 如果窗口的和大于k,尝试移除窗口的头部元素,并更新窗口的和。

- 如果窗口的和小于k,继续遍历下一个元素。

代码实现

python

def subarraySum(nums, k):


if not nums or k <= 0:


return []



hashmap = {0: -1} 初始化哈希表,用于存储窗口的和及其对应的索引


result = []


window_sum = 0



for i in range(len(nums)):


window_sum += nums[i]



如果窗口的和等于k,将当前窗口的索引加入结果列表


if window_sum == k:


result.append(i - hashmap[window_sum])



如果窗口的和大于k,尝试移除窗口的头部元素,并更新窗口的和


while window_sum > k and hashmap.get(window_sum - nums[i - 1], -1) != -1:


window_sum -= nums[hashmap[window_sum - nums[i - 1]]]


hashmap.pop(window_sum - nums[i - 1])



将当前窗口的和及其对应的索引加入哈希表


hashmap[window_sum] = i



return result


总结

本文深入探讨了LeetCode中的两个经典问题:最大值滑动窗口和和为K的滑动窗口。通过使用双端队列和哈希表,我们实现了高效的解决方案。这些问题的解决思路和代码实现对于理解和掌握数组滑动窗口问题具有重要意义。在实际编程中,我们可以根据具体问题选择合适的算法和数据结构,以达到最优的性能。