给你一个整数数组 nums 和一个整数 k。
如果某个子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。
请返回这个数组中「优美子数组」的数目。
示例 1:
输入:nums = [1,1,2,1,1], k = 3
输出:2
解释:包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] 。
示例 2:
输入:nums = [2,4,6], k = 1
输出:0
解释:数列中不包含任何奇数,所以不存在优美子数组。
示例 3:
输入:nums = [2,2,2,1,2,2,1,2,2,2], k = 2
输出:16
提示:
1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= k <= nums.length
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-number-of-nice-subarrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
对于输入 = [2,2,2,1,2,2,1,2,2,2],k = 2,[1, 2, 2, 1]这部分必须包含在子数组里。
所以包含两个奇数的子数组开始的下标可以为[0, 3], 结束的下标可以为[-4, -1], 所以答案为4 * 4 = 16个。
先找到nums里每个奇数的下标,放在odd数组里,
然后对于每个奇数odd[i],找到前一个奇数odd[i - 1]的下标, 找到下k个奇数odd[i + k]的下标,
这样就可以知道, 包含奇数odd[i] 到 odd[i + k - 1]的子数组可以选的起点和终点,
起点个数为 odd[i] - odd[i - 1], 终点个数为odd[i + k] - odd[i + k - 1]。
然后乘一下起点个数和终点个数即可得到, 包含奇数odd[i] 到 odd[i + k - 1]的子数组的个数。
class Solution(object):
def numberOfSubarrays(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
if not nums:
return 0
res = 0
odd = []
for i, num in enumerate(nums):
if num % 2:
odd.append(i)
if len(odd) < k:
return 0
for i in range(len(odd)):
if i + k > len(odd):
break
if i:
last = odd[i - 1]
else:
last = -1
if i + k < len(odd):
nxt = odd[i + k]
else:
nxt = len(nums)
left = odd[i] - last
right = nxt - odd[i + k - 1]
res += left * right
return res