生成平衡数组的方案数
难度:
标签:
题目描述
代码结果
运行时间: 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],而不考虑后面元素下标的变化?
▷🦆
在更新left_odd和left_even的值时,为什么是在判断平衡之后而不是之前更新这些值?
▷🦆
在遍历过程中,如果i是奇数下标,为什么要从even中减去nums[i],这里的逻辑是基于什么考虑?
▷🦆
题解中提到的平衡条件是'left_odd + even == left_even + odd',能否详细解释这个条件是如何得出的?
▷