leetcode
leetcode 1501 ~ 1550
生成平衡数组的方案数

生成平衡数组的方案数

难度:

标签:

题目描述

代码结果

运行时间: 137 ms, 内存: 21.0 MB


// Java Stream Solution

/*
 * 思路:
 * 1. 计算初始数组中奇数和偶数下标的元素之和。
 * 2. 遍历数组,每次删除一个元素后,重新计算剩余数组的奇数和偶数下标元素之和,判断是否为平衡数组。
 * 3. 使用流的方式处理前缀和的计算,以优化计算过程。
 */

import java.util.stream.IntStream;

public class StreamSolution {
    public int waysToMakeFair(int[] nums) {
        int n = nums.length;
        int totalOddSum = IntStream.range(0, n).filter(i -> i % 2 != 0).map(i -> nums[i]).sum();
        int totalEvenSum = IntStream.range(0, n).filter(i -> i % 2 == 0).map(i -> nums[i]).sum();

        int leftOddSum = 0, leftEvenSum = 0;
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (i % 2 == 0) {
                totalEvenSum -= nums[i];
            } else {
                totalOddSum -= nums[i];
            }

            if (leftOddSum + totalEvenSum == leftEvenSum + totalOddSum) {
                count++;
            }

            if (i % 2 == 0) {
                leftEvenSum += nums[i];
            } else {
                leftOddSum += nums[i];
            }
        }

        return count;
    }
}

解释

方法:

本题解采用前缀和思想,首先计算整个数组的奇数下标元素和(odd)与偶数下标元素和(even)。然后遍历数组,模拟删除每个位置的元素,通过维护两个变量left_odd和left_even来记录当前位置左侧的奇数和偶数和。对于每个位置i,首先从总和中减去当前元素,然后比较左侧偶数和加上右侧奇数和是否等于左侧奇数和加上右侧偶数和,如果相等,则当前删除操作产生的数组是平衡的。之后更新左侧奇偶和。最后返回所有平衡数组的方案数。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在处理删除操作时可以直接从odd或even中减去nums[i],而不考虑后面元素下标的变化?
在删除操作的模拟中,我们并不真正地改变数组结构或其元素的下标。我们只是在逻辑上考虑如果某个元素被删除,会如何影响到总的奇数和偶数和。通过维护odd和even两个变量来分别记录所有奇数下标和偶数下标元素的和,然后根据当前元素的下标性质(奇或偶),直接从相应的和中减去该元素。这样做是因为我们只是想知道在不同删除情况下的偶和奇和的状态,而非改变数组的物理结构或下标。
🦆
在更新left_odd和left_even的值时,为什么是在判断平衡之后而不是之前更新这些值?
在判断平衡数组条件之前,需要确保left_odd和left_even反映的是删除当前元素之前的状态,即当前元素左侧的奇偶和。如果先更新left_odd和left_even,那么比较的就不是删除当前元素之前的状态,而是包含了当前元素的新状态,这将导致错误的平衡判断。因此,我们先进行平衡性判断,然后再更新这些值以反映下一个元素处理时的左侧奇偶和。
🦆
在遍历过程中,如果i是奇数下标,为什么要从even中减去nums[i],这里的逻辑是基于什么考虑?
在数组中,下标从0开始计数,因此偶数下标实际上是0, 2, 4, ..., 而奇数下标是1, 3, 5, ...。在题目中定义奇数和odd为奇数下标元素的和,偶数和even为偶数下标元素的和。因此,当我们遇到一个奇数下标的元素时,这个元素事实上是被计算在偶数和even中的。所以从even中减去这个奇数下标的元素是为了维护正确的偶数和状态。
🦆
题解中提到的平衡条件是'left_odd + even == left_even + odd',能否详细解释这个条件是如何得出的?
平衡条件的核心思想是在任何删除元素的操作后,剩余数组的奇数下标元素和应等于偶数下标元素和。当删除i位置的元素后,i左侧的奇数和偶数和分别为left_odd和left_even。i右侧的奇数和偶数和可以通过总奇偶和减去左侧奇偶和和当前元素得出。特别地,我们需要注意当前元素下标的奇偶性,来决定它属于奇数和还是偶数和。最终,我们希望左侧奇数和加上右侧偶数和等于左侧偶数和加上右侧奇数和,这样确保整个数组在删除某个元素后保持平衡。

相关问题