题目:
给你一个整数数组 nums 和一个整数 k。如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。请返回这个数组中「优美子数组」的数目。
示例:
输入:nums = [1,1,2,1,1], k = 3
输出:2(包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] )
来源:力扣(LeetCode)
方法一:暴力傻子破解法
明显最傻的方法就是直接两个for循环,从nums中取出一个大于K的list,并且判断这个list的奇数个数,如果奇数个数为K,则number加一。然而这个方法明显不行,因为会超时。。。
1 # 暴力破解 2 class Solution(object): 3 def numberOfSubarrays(self, nums, k): 4 number = 0 5 for i in range(len(nums)-k+1): 6 flag = 0 7 for j in range(i+k,len(nums)+1): 8 if flag == 0: 9 sub = nums[i:j] 10 count = 0 11 for s in sub: 12 if s % 2 != 0: 13 count += 1 14 if count > k: 15 break 16 if count == k: 17 number +=1 18 flag = 1 19 else: 20 if nums[j-1] % 2 == 0: 21 number += 1 22 else: 23 break 24 return number
方法二:换个角度思考
找到第 i 个奇数的位置,找到第i+k-1个奇数的位置,这就确定了两个边界,再看这两个边界的活动范围有多大就知道有几种组合了。左边界的活动范围在当前第 i 个奇数到上一个奇数(即 i-1)之间,右边界的活动范围在当前第 i+k-1 到下一个边界(即 i+k)之间。左边范围 * 右边活动范围 在各个位置上的累加就是结果。
1 # 转换思路 2 class Solution(object): 3 def numberOfSubarrays(self, nums, k): 4 index = [-1] 5 for i in range(len(nums)): 6 if nums[i] % 2 == 1: 7 index.append(i) 8 index.append(len(nums)) 9 10 count = 0 11 for i in range(1, len(index)-k): 12 count += (index[i] - index[i-1]) * (index[i+k]-index[i+k-1]) 13 14 return count
原文:https://www.cnblogs.com/fsencen/p/leetcode3.html