leetcode
leetcode 2601 ~ 2650
连续天数的最高销售额

连续天数的最高销售额

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 64 ms, 内存: 18.4 MB


/*
 * 题目思路:
 * 使用 Java Stream 的话,需要结合 IntStream 和一些辅助方法来实现。
 * 尽管 Kadane 算法不适合完全通过 Stream API 实现,我们可以使用类似方法结合 Stream 实现。
 */

import java.util.stream.IntStream;

public class Solution {
    public int maxSubArray(int[] sales) {
        // 使用数组记录当前子数组和和最大子数组和
        int[] result = IntStream.range(0, sales.length)
            .mapToObj(i -> new int[]{sales[i], sales[i]})
            .reduce(new int[]{sales[0], sales[0]}, (acc, val) -> {
                // 计算当前子数组和
                acc[0] = Math.max(val[0], acc[0] + val[0]);
                // 更新最大子数组和
                acc[1] = Math.max(acc[1], acc[0]);
                return acc;
            });
        return result[1];
    }
}

解释

方法:

题解采用了'Kadane算法',用以解决最大子数组和的问题。首先初始化最大和max_sum为负无穷,当前和cur_sum为0。遍历数组中的每个元素,将当前元素累加到cur_sum上。如果cur_sum更新后的值比max_sum大,则更新max_sum。之后,如果cur_sum小于0,将其重置为0,因为任何负的当前和都不会对找到一个更大的子数组和有帮助。这样,通过一次遍历数组,就能得到最大的子数组和。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在Kadane算法中,当当前和cur_sum小于0时,需要将其重置为0?
在Kadane算法中,如果当前和cur_sum小于0,意味着加上当前子数组的和会让整体和更小,这对寻找最大子数组和是不利的。因此,将cur_sum重置为0是为了舍弃当前的负累积和,从下一个元素重新开始计算新的子数组和,以寻找可能存在的更大的子数组和。这种做法确保了算法总是尝试捕捉到最有利的起点,从而最大化整体的子数组和。
🦆
Kadane算法是否能够处理所有元素都是负数的情况?如果可以,它是如何找到最大子数组和的?
Kadane算法能够处理所有元素都是负数的情况。即使所有元素都是负数,算法仍会通过遍历每个元素来更新最大子数组和max_sum。在这种情况下,最大子数组和将是数组中单个最小负值(即绝对值最小的负数),因为任何负数相加都会产生更小的和。因此,即使所有数都为负,Kadane算法仍然能找到最大子数组和,即这些负数中的最大值。
🦆
在Kadane算法中,如果数组中包含0或者正负相间的数,这种情况对算法的影响是什么?
在Kadane算法中,如果数组包含0或正负相间的数,算法仍然有效。0的存在不会对当前和产生负面影响,但也不增加和;在计算过程中,0可以作为连接正数的桥梁,有助于维持当前和。正负相间的数会使得当前和经常重置,但Kadane算法通过不断比较和更新最大子数组和max_sum,能够有效地处理这种波动,最终找到最优的子数组和。
🦆
在实现Kadane算法时,为何要初始化max_sum为负无穷大而不是0?
在实现Kadane算法时,初始化max_sum为负无穷大是为了确保算法能够正确处理所有元素都是负数的情况。如果初始化为0,在全是负数的数组中,算法将错误地返回0作为最大子数组和,这是不正确的,因为最大子数组和应该是数组中的最大负数。初始化为负无穷大确保了无论数组内容如何,max_sum总能被数组中的任何值(包括负数)更新。

相关问题