2025-08-03:统计元素和差值为偶数的分区方案。用go语言,给定一个长度为 n 的整数数组 nums。
我们需要将数组通过一个下标 i(满足 0 <= i < n - 1)分成两个非空部分:
- 左侧子数组包含从索引 0 到 i 的所有元素;
- 右侧子数组包含从索引 i + 1 到 n - 1 的所有元素。
接下来,计算左右两个子数组元素和的差值。
请统计并返回所有使得这个差值为偶数的分割方式数量。
2 <= n == nums.length <= 100。
1 <= nums[i] <= 100。
输入:nums = [10,10,3,7,6]。
输出:4。
解释:
共有 4 个满足题意的分区方案:
[10]、[10, 3, 7, 6] 元素和的差值为 10 - 26 = -16 ,是偶数。
[10, 10]、[3, 7, 6] 元素和的差值为 20 - 16 = 4,是偶数。
[10, 10, 3]、[7, 6] 元素和的差值为 23 - 13 = 10,是偶数。
[10, 10, 3, 7]、[6] 元素和的差值为 30 - 6 = 24,是偶数。
题目来自力扣3432。
解决步骤
- 计算总和:
- 首先计算整个数组的总和
s。这可以通过遍历数组一次完成。 - 总和
s = left_sum + right_sum。
- 差值的表达式:
- 差值
diff = left_sum - right_sum。 - 可以重写为
diff = left_sum - (s - left_sum) = 2 * left_sum - s。 - 因此,
diff为偶数等价于2 * left_sum - s为偶数。
- 判断差值为偶数的条件:
-
2 * left_sum - s为偶数,可以简化为s和2 * left_sum的奇偶性相同。 - 因为
2 * left_sum始终是偶数,所以s必须是偶数才能满足diff为偶数。 - 因此:
- 如果
s是偶数,那么diff为偶数的条件是left_sum可以是任意值(因为2 * left_sum是偶数,s是偶数,偶数减偶数为偶数)。 - 如果
s是奇数,那么diff为奇数的条件是left_sum可以是任意值(因为2 * left_sum是偶数,s是奇数,偶数减奇数为奇数)。
- 但实际上,
diff为偶数的条件是2 * left_sum - s为偶数,即s和2 * left_sum同奇偶。由于2 * left_sum总是偶数,所以s必须是偶数才能满足diff为偶数。 - 因此:
- 如果
s是偶数,那么所有分割方式都满足diff为偶数(因为diff = 2 * left_sum - s,偶数减偶数为偶数)。 - 如果
s是奇数,那么没有分割方式满足diff为偶数(因为偶数减奇数为奇数)。
- 所以:
- 如果
s是偶数,分割方式的数量为n - 1(因为有n - 1个可能的分割点)。 - 如果
s是奇数,分割方式的数量为0。
- 验证示例:
- 示例输入:
nums = [10, 10, 3, 7, 6]。 - 计算总和
s = 10 + 10 + 3 + 7 + 6 = 36。 -
36是偶数,因此分割方式的数量为n - 1 = 5 - 1 = 4。 - 这与题目给出的解释一致。
时间和空间复杂度
- 时间复杂度:
- 计算总和
s需要遍历整个数组一次,时间复杂度为O(n)。 - 判断
s的奇偶性和返回结果是O(1)。 - 因此,总时间复杂度为
O(n)。
- 空间复杂度:
- 只使用了常数空间(变量
s),因此额外空间复杂度为O(1)。
总结
- 统计所有分割方式的关键是判断整个数组的总和
s的奇偶性。 - 如果
s是偶数,所有n - 1个分割方式都满足条件;否则,没有满足条件的分割方式。 - 时间和空间复杂度都非常高效。
Go完整代码如下:
package mainimport ("fmt"
)func countPartitions(nums []int) int {s := 0for _, x := range nums {s += x}if s%2 == 0 {return len(nums) - 1}return 0
}func main() {nums := []int{10, 10, 3, 7, 6}result := countPartitions(nums)fmt.Println(result)
}
Python完整代码如下:
# -*-coding:utf-8-*-def count_partitions(nums):s = sum(nums)if s % 2 == 0:return len(nums) - 1return 0if __name__ == "__main__":nums = [10, 10, 3, 7, 6]result = count_partitions(nums)print(result)
