Переменный размер скользящего окна – Сумма подсети равна K

Вопрос или проблема

Я пытался решить задачу со сдвигающимися окнами переменного размера, но мой тестовый случай не проходит для
nums =[-1,-1,1], k =0 , Выход=0, Ожидаемый =1
https://leetcode.com/problems/subarray-sum-equals-k/description/
вот мое решение вышеуказанной задачи, я знаю, что доступно много разных решений, но я хочу решить это своим способом. Мог бы кто-нибудь улучшить мою логику ниже. Спасибо

private static int subarraySum(int[] nums, int k) {

        int i = 0;
        int j = 0;
        int sum = 0;
        int count = 0;

            while (j < nums.length) {
                // условие
                sum = sum + nums[j];

                if (sum < k) {
                    j++;
                } else if (sum == k) {
                    count = count + 1;
                    sum = sum - nums[i];
                    i++;
                    j++;
                } else if (sum > k) {
                    while (sum > k) {
                        sum = sum - nums[i];
                        if (sum > 0 && sum == k) {
                            count = count + 1;
                        }
                        i++;
                    }
                    j++;
                }

            }
        
        return count;
    }

Тестовый случай не проходит

Ответ или решение

Для решения задачи "Сумма подмассива равна K" с использованием подхода переменного размера скользящего окна может потребоваться доработка вашего алгоритма. Давайте проанализируем вашу реализацию и выявим недостатки.

Основные аспекты проблемы

Задача заключается в том, чтобы найти количество подмассивов в массиве nums, сумма элементов которых равна заданному числу k. Ваша реализация, хотя и близка к решению, имеет некоторые логические ошибки, которые не позволяют правильно обрабатывать определенные случаи, такие как массив с отрицательными числами, как в вашем тестовом случае nums = [-1, -1, 1] и k = 0.

Ошибки в вашем коде

  1. Условия увеличения указателей: Условие if (sum < k) некорректно. При наличии отрицательных чисел сумма может оставаться меньше, но все равно встречаться подмассив с нужной суммой. Также следует учитывать возможность появления равных и отрицательных сумм, которые могут быть не пойманы.

  2. Сложная логика: Использование внутреннего цикла while (sum > k) может привести к пропуску подмассивов; ваш алгоритм не учитывает, что при изучении текущего окна можно выделить более одного подмассива, сумма которых равна k.

Оптимальное решение

Для решения задачи с помощью хэш-таблицы можно использовать метод префиксных сумм, который более эффективен и просто отвечает на поставленный вопрос. Реализация будет выглядеть следующим образом:

import java.util.HashMap;

private static int subarraySum(int[] nums, int k) {
    HashMap<Integer, Integer> prefixMap = new HashMap<>();
    prefixMap.put(0, 1);  // Сумма 0 имеет 1 появление по умолчанию
    int count = 0;
    int sum = 0;

    for (int num : nums) {
        sum += num;  // Обновляем текущую сумму

        // Проверяем, есть ли префиксная сумма, которая в сочетании с текущей суммой дает k
        if (prefixMap.containsKey(sum - k)) {
            count += prefixMap.get(sum - k);  // Увеличиваем счетчик
        }

        // Добавляем текущую сумму в карту
        prefixMap.put(sum, prefixMap.getOrDefault(sum, 0) + 1);
    }

    return count;
}

Объяснение решения

  1. Префиксные суммы: Мы используем переменную sum для хранения текущей суммы элементов. При каждом добавлении нового элемента в массив мы обновляем эту сумму.

  2. Хэш-таблица: Хранить количество появлений каждой префиксной суммы позволяет нам быстро проверять, сколько раз необходимая префиксная сумма (т.е. sum - k) встречалась. Если эта сумма уже встречалась, значит существует подмассив, сумма которого равна k.

  3. Производительность: Данная реализация имеет временную сложность O(n), что значительно более эффективно по сравнению с вашим оригинальным подходом.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...