Минимальный субарм суммы в O (N) алгоритмом Кадане

Мы все знаем о субаре максимальной суммы и известном алгоритме Кадане. Но можем ли мы использовать тот же алгоритм, чтобы найти минимальную сумму?

Мой выбор:

измените знак и найдите в нем максимальную сумму, такую ​​же, как способ вычисления максимального субара. Чем изменится знак элементы в массиве, чтобы сделать его в исходном состоянии.

Пожалуйста, помогите мне в исправлении алгоритма, если у него есть какие-либо проблемы.

corner case: Я знаю, что есть проблема, если все элементы положительны, и мы можем справиться с этим случаем, выполнив некоторую предварительную обработку, т.е. пройдем массив, если все + ve, а не просто возвращают минимальное число из массива.

Вышеупомянутый алгоритм упоминания будет работать и хорошо поддерживается (объясняется) dasblinkenlight.

Ответ 1

Будет ли описанный мной подход работать, чтобы найти минимальную сумму?

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

Я знаю, что есть проблема, если все элементы положительные

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

Ваш модифицированный алгоритм будет делать то же самое, если все числа будут положительными: снова ваше лучшее решение - не принимать номера вообще.

Если вы добавите требование о том, что диапазон, возвращаемый из алгоритма, может быть пустым, вы можете немного изменить алгоритм, чтобы найти наименьшее положительное число (или наибольшее отрицательное число), если алгоритм Кадане возвращает пустой диапазон как оптимальное решение.

Ответ 2

Просто замените max на min.

//O(n)
public static int minSubArraySum(int[] arr) {
    int minSum = 0;
    int curSum = 0;
    for (int num : arr) {
        curSum += num;
        minSum = Math.min(minSum, curSum);
        curSum = Math.min(curSum, 0);
    }
    return minSum;
}

Ответ 3

static void subArraySumMin(int a[]) {
        int minendingHere = 0;
        int minSoFar = a[0];

        for (int i = 1; i < a.length; i++) {
            minendingHere = Math.min(a[i], minendingHere + a[i]);
            minSoFar = Math.min(minSoFar, minendingHere);
        }

        System.out.println(minSoFar);
    }