返回

双指针优化滑动窗口,轻松搞定 Leetcode 2302

后端

问题

给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的和的绝对值小于等于 k 的子数组数目。

示例 1:

输入:nums = [1,0,1,2,3], k = 4
输出:3
解释:满足要求的子数组分别是:[1,0,1][2][3]

示例 2:

输入:nums = [3,2,1,5,1], k = 3
输出:4
解释:满足要求的子数组分别是:[3,2,1][2,1][1,5,1][5,1]

思路分析

这个问题可以转换成求和不超过 k 的连续子数组的个数。我们可以使用滑动窗口算法来解决这个问题。滑动窗口算法的基本思想是:从数组的开头开始,每次移动窗口一个元素,直到窗口中的元素和超过 k 。然后,我们把窗口向右移动一个元素,继续这个过程,直到到达数组的末尾。在移动窗口的过程中,我们统计满足条件的子数组的个数。

双指针算法是滑动窗口算法的一种优化。双指针算法的基本思想是:使用两个指针 left 和 right 来表示窗口的左右边界。从数组的开头开始,left 和 right 指针都指向第一个元素。然后,我们移动 right 指针,直到窗口中的元素和超过 k 。然后,我们移动 left 指针,直到窗口中的元素和不再超过 k 。这样,我们就找到了一个满足条件的子数组。我们把这个子数组的个数加到计数器中,然后继续移动 right 指针,重复这个过程,直到 right 指针到达数组的末尾。

代码实现

def countSubarrays(nums, k):
    """
    :type nums: List[int]
    :type k: int
    :rtype: int
    """
    left, right = 0, 0
    subarrays = 0
    sum = 0

    while right < len(nums):
        sum += nums[right]
        while sum > k:
            sum -= nums[left]
            left += 1
        subarrays += right - left + 1
        right += 1

    return subarrays


# 测试代码
nums = [1, 0, 1, 2, 3]
k = 4
print(countSubarrays(nums, k))  # 3

nums = [3, 2, 1, 5, 1]
k = 3
print(countSubarrays(nums, k))  # 4

时间复杂度分析

滑动窗口算法的时间复杂度为 O(n),其中 n 是数组的长度。这是因为我们只需要遍历数组一次。双指针算法的时间复杂度也是 O(n),因为我们只需要遍历数组一次。

总结

滑动窗口算法和双指针算法都是解决这类问题的高效算法。滑动窗口算法和双指针算法的思想是一样的,都是通过移动窗口来统计满足条件的子数组的个数。但是,双指针算法比滑动窗口算法更简单,更容易理解。

感谢您阅读本文。如果您有任何问题,请随时留言。