Изучение методов поиска минимального размера подмассива с суммой, большей заданного значения

В этой статье мы углубимся в различные методы поиска минимального размера подмассива, сумма которого превышает указанное значение, часто называемое «минимальным размером подмассива с суммой >k». Мы предоставим примеры кода для каждого метода, чтобы проиллюстрировать их реализацию. Независимо от того, являетесь ли вы новичком или опытным программистом, это подробное руководство предоставит вам несколько подходов для эффективного решения этой проблемы.

Методы:

  1. Подход грубой силы:
    Метод грубой силы включает в себя проверку всех возможных подмассивов и вычисление их сумм. Мы можем перебирать массив и поддерживать два указателя, представляющие начало и конец подмассива. Вот пример кода:
def min_subarray_size_brute_force(arr, k):
    n = len(arr)
    min_size = float('inf')

    for i in range(n):
        for j in range(i, n):
            subarray_sum = sum(arr[i:j+1])
            if subarray_sum > k:
                min_size = min(min_size, j - i + 1)

    return min_size
  1. Техника скользящего окна:
    Техника скользящего окна представляет собой оптимизированный подход, который снижает временную сложность до O(n). Он использует два указателя для поддержания окна в массиве. Перемещая окно при определенных условиях, мы можем найти минимальный размер подмассива. Вот пример:
def min_subarray_size_sliding_window(arr, k):
    n = len(arr)
    min_size = float('inf')
    window_sum = 0
    left = 0

    for right in range(n):
        window_sum += arr[right]

        while window_sum > k:
            min_size = min(min_size, right - left + 1)
            window_sum -= arr[left]
            left += 1

    return min_size
  1. Техника префиксной суммы:
    Техника префиксной суммы подходит, когда массив содержит положительные целые числа. Он предварительно вычисляет массив сумм префиксов, что позволяет нам вычислять сумму любого подмассива за постоянное время. Найдя минимальный размер подмассива на основе сумм префиксов, мы можем эффективно решить проблему. Вот пример:
def min_subarray_size_prefix_sum(arr, k):
    prefix_sum = [0] * (len(arr) + 1)
    for i in range(1, len(arr) + 1):
        prefix_sum[i] = prefix_sum[i - 1] + arr[i - 1]

    min_size = float('inf')
    left = 0
    right = 1

    while right <= len(arr):
        subarray_sum = prefix_sum[right] - prefix_sum[left]
        if subarray_sum > k:
            min_size = min(min_size, right - left)
            left += 1
        else:
            right += 1

    return min_size
  1. Двоичный поиск.
    Если массив содержит отрицательные числа, мы можем использовать двоичный поиск, чтобы найти минимальный размер подмассива. Этот подход требует отсортированного массива сумм префиксов. Вот пример:
import bisect
def min_subarray_size_binary_search(arr, k):
    prefix_sum = [0]
    for num in arr:
        prefix_sum.append(prefix_sum[-1] + num)

    min_size = float('inf')

    for i in range(len(prefix_sum)):
        target = k + prefix_sum[i]
        j = bisect.bisect_left(prefix_sum, target, i + 1)

        if j != len(prefix_sum):
            min_size = min(min_size, j - i)

    return min_size