📅  最后修改于: 2023-12-03 14:53:52.052000             🧑  作者: Mango
给定一个长度为 N 的正整数数组 nums 和一个整数 K,将数组拆分为 K 个不相交的子数组,使得每个子数组的和都是奇数。
题目可以转化为在数组中选择 K-1 个位置将数组分割成 K 段,使得每段的和都是奇数,因为共有 K-1 个分割点,可列出如下表格:
| 分割点1 | 分割点2 | ... | 分割点K-1 | | ------ | ------ | --- | --------- | | 0 | i_1 | ... | i_{k-2} | | i_1 | i_2 | ... | i_{k-3} | | ... | ... | ... | ... | | i_{k-3}| i_{k-2}| ... | N-1 |
其中,i_j 表示第 j 个分割点的位置,因为每段和都必须是奇数,而奇数 + 奇数 = 偶数,因此每段中必须有一个偶数,也就是说对于每个 j,均有:
(nums[i_j]+...+nums[i_{k-2}]) % 2 == 1
进一步化简:
nums[i_j] % 2 + ... + nums[i_{k-2}] % 2 == k - j - 1 (对于所有 0 <= j <= k - 2)
因此,可以枚举所有可能的分割点,统计符合条件的方案数量即可。
def numOfSubarrays(nums: List[int], k: int) -> int:
n, ans = len(nums), 0
presum = [0] * (n + 1)
for i in range(1, n + 1):
presum[i] = presum[i - 1] + nums[i - 1]
for i in range(k - 1, n):
if (presum[i + 1] - presum[i + 1 - k]) % 2 == 1:
ans += 1
for j in range(k, i + 1):
if (presum[i + 1] - presum[j - 1]) % 2 == 1:
ans += 1
return ans