数组中的灵活思想之一——滑动窗口(附LeetCode实例)

滑动数组的基本思想

在编程中,处理数组(或列表)时,滑动数组是一种非常有用的技术。它通常用于解决需要在连续的子数组或子列表上执行操作的问题。这种技术的关键思想是通过在数组上"滑动"一个固定大小的窗口来解决问题。让我们深入了解滑动数组的原理,并通过相应的示例演示其应用。

滑动数组的基本原理

滑动数组的核心概念是使用两个指针(或索引)来定义一个窗口,并在数组上移动该窗口以执行特定操作。这样的窗口通常是固定大小的,而滑动的步长取决于问题的要求。这种方法的优势在于它能够在线性时间内解决问题,而不需要嵌套的循环。

通常应用场景

1. 寻找子数组中总和的最大/最小值

假设我们有一个包含整数的数组,我们想要找到长度为 k 的子数组的最大值。使用滑动数组的方法,我们可以轻松地在线性时间内解决这个问题。同理,我们找特定条件的子数组也是如此。

ini 复制代码
def max_in_subarray(nums, k):
    max_sum = float('-inf')
    current_sum = 0

    for i in range(len(nums)):
        current_sum += nums[i]

        if i >= k - 1:
            max_sum = max(max_sum, current_sum)
            current_sum -= nums[i - (k - 1)]

    return max_sum

nums = [1, 2, 3, 1, 4, 2, 3]
print(max_in_subarray(nums, k=2))  # 输出6,对应大小为2的子数组为[4,2]
print(max_in_subarray(nums, k=3))  # 输出9,对应大小为3的子数组为[4,2,3]

2. 寻找子数组中的平均值

类似地,我们可以使用滑动数组来找到数组中长度为 k 的子数组的平均值。

less 复制代码
def average_in_subarray(nums, k):
    averages = []

    current_sum = sum(nums[:k])
    averages.append(current_sum / k)

    for i in range(k, len(nums)):
        current_sum += nums[i] - nums[i - k]
        averages.append(current_sum / k)

    return averages

nums = [1, 2, 3, 1, 4, 2, 3]
print(average_in_subarray(nums, k=6))  
# 输出[2.1666666666666665, 2.5],对应计算的子数组为[1, 2, 3, 1, 4, 2],[2, 3, 1, 4, 2, 3]
print(average_in_subarray(nums, k=4))  
# 输出[1.75, 2.5, 2.5, 2.5],对应计算的子数组为[1, 2, 3, 1],[2, 3, 1, 4],[3, 1, 4, 2],[1, 4, 2, 3]

【LeetCode实例:219. 存在重复元素 II

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 ij ,满足 nums[i] == nums[j]abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false

示例 1:

ini 复制代码
输入: nums = [1,2,3,1], k = 3
输出: true

示例 2:

ini 复制代码
输入: nums = [1,0,1,1], k = 1
输出: true

示例 3:

ini 复制代码
输入: nums = [1,2,3,1,2,3], k = 2
输出: false

提示:

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9
  • 0 <= k <= 10^5

python题解如下:

python 复制代码
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        n = len(nums)
        s = set()
        for i in range(n):
            if i > k:         # 子数组超过k的范围则将子数组(集合s)最前面的元素去掉
                s.remove(nums[i-k-1])
            if nums[i] in s:  # 如果子数组中存在相同的元素则返回True
                return True
            s.add(nums[i])    # 下标小于等于k时,即起始滑窗长度还不足k+1,直接往滑窗将元素nums[i]加入到集合s中
        return False

总结

滑动数组是一种灵活而高效的方法,适用于解决许多与连续子数组有关的问题。通过定义适当大小的窗口,并在数组上移动该窗口,我们可以在线性时间内解决许多复杂的问题。这种技术在处理大规模数据时尤为有用,因为它避免了嵌套循环,提高了算法的效率。在编写代码时,考虑使用滑动数组作为解决问题的工具,以提高代码的可读性和性能。

如果有兴趣的小伙伴也可以去试下209. 长度最小的子数组,此题也是滑动窗口思想解题,本人也是正在学习中,如有错误的地方欢迎大家指正,同时也希望这篇文章能给大家带来帮助。

相关推荐
多彩电脑1 小时前
Python的tkinter如何把日志弄进文本框(Text)
python·用户界面
小馒头学python1 小时前
【Python爬虫五十个小案例】爬取豆瓣电影Top250
开发语言·爬虫·python
black0moonlight7 小时前
ISAAC Gym 7. 使用箭头进行数据可视化
开发语言·python
程序员黄同学7 小时前
Python 中如何创建多行字符串?
前端·python
feilieren8 小时前
信创改造 - TongRDS 替换 Redis
java·spring boot·后端
hani19908 小时前
beikeshop 与swoole结合,让网站打开飞起
后端·swoole
一点一木8 小时前
AI与数据集:从零基础到全面应用的深度解析(超详细教程)
人工智能·python·tensorflow
A.sir啊8 小时前
Python知识点精汇:集合篇精解!
python·pycharm
周某人姓周8 小时前
利用爬虫爬取网页小说
爬虫·python
花生糖@8 小时前
OpenCV图像基础处理:通道分离与灰度转换
人工智能·python·opencv·计算机视觉