当前位置: 首页 > news >正文

[python 刷题] 1248 Count Number of Nice Subarrays

[python 刷题] 1248 Count Number of Nice Subarrays

题目如下:

Given an array of integers nums and an integer k. A continuous subarray is called nice if there are k odd numbers on it.

Return the number of nice sub-arrays.

这道题和 1343 Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold 挺像的

双指针

先声明,我的写法不是最有效的,其他的双指针/滑动窗口的解法会更加的高效,不过我感觉对我来说这么写是最好理解的

首先题目要求必须要有 k 个奇数,以题目中 Input: nums = [2,2,2,1,2,2,1,2,2,2], k = 2 为例,它的 base case 是这样的:

在这里插入图片描述

同时,因为两边都是偶数,因此指针是可以向两边延长的,演唱后也都是满足题目需求,即,子数组中有 k 个奇数

首先用两个指针指向 l l l r r r,使用 c o u n t e r counter counter 计算 [ l , l + 1 , . . . , r ] [l, l + 1, ..., r] [l,l+1,...,r] 中的奇数。每次移动 r r r 的时候,更新 c o u n t e r counter counter,这时候会出现两个需要照顾的条件:

  1. c o u n t e r > k counter > k counter>k

    这个时候就需要不断移动 l l l,一直到 c o u n t e r = = k counter == k counter==k

  2. c o u n t e r = = k counter == k counter==k

    依旧以上面的案例来说,因为左侧指针没有动过,实际上应该是这样的情况:

    在这里插入图片描述

    这时候新建一个 t e m p temp temp 指针代替右侧指针,并且将 d i f f diff diff 保存下来:

    在这里插入图片描述

    这里的 d i f f diff diff 代表着不同的组合,即 l l l 移动一格时所会产生的不同组合,在移动左侧指针时,每次添加 d i f f diff diff 即可

代码如下:

class Solution:def numberOfSubarrays(self, nums: List[int], k: int) -> int:n = len(nums)res, count = 0, 0l, r = 0, 0while r < n:if nums[r] % 2:count += 1while count > k:if nums[l] % 2:count -= 1l += 1if count == k:res += 1t = r + 1while t < n and not nums[t] % 2:res += 1t += 1diff = t - rr = t - 1while l < r and not nums[l] % 2:res += diffl += 1r += 1return res

prefix sum

使用 prefix sum 就比较简单了,这里是将所有出现奇数的次数全都保存下来到一个变量中,同时,会形成一个 {odd_num: even_num_freq + 1} 的对应关系,这样可以保存不同的组合

Input: nums = [2,2,2,1,2,2,1,2,2,2], k = 2,它的键值对的关系为 {0: 4, 1: 3, 2: 4},其中保存的对应关系为:

0: [default_value, 2,2,2]
1: [1,2,2]
2: [1,2,2,2]

这样,通过 count[odd_count - k] 就能够获取对应的变化,也就是上一个解法中的 d i f f diff diff,代码如下:

class Solution:def numberOfSubarrays(self, nums: List[int], k: int) -> int:n = len(nums)# 这里使用数组而非字典,不过其原理是一样的# 使用 n + 1 是因为 0 为没有出现 odd 的情况# 而当数组中所有的成员都是 odd 时,count 的长度就为 n + 1count = [0] * (n + 1)# 这个是 base case# 空数组也是一个合法的 subarraycount[0] = 1odd_count = 0res = 0for num in nums:if num % 2 == 1:odd_count += 1if odd_count >= k:res += count[odd_count - k]count[odd_count] += 1return res
http://www.lryc.cn/news/218771.html

相关文章:

  • 堆叠注入 [GYCTF2020]Blacklist1
  • 算法:Java构建二叉树并递归实现二叉树的前序、中序、后序遍历
  • 既然有了字节流,为什么还要有字符流?
  • 3+单细胞+代谢+WGCNA+机器学习
  • 音乐推荐与管理系统Python+Django网页界面+协同过滤推荐算法
  • (论文阅读15/100)You Only Look Once: Unified, Real-Time Object Detection
  • init进程启动过程
  • 全网最详细的【shell脚本的入门】
  • CH10_简化条件逻辑
  • nn.LayerNorm解释
  • Springboot搭建微服务案例之Eureka注册中心
  • 【MySQL】用户管理权限控制
  • 若依框架前后端分离版服务器部署,前端nginx的配置
  • 基于单片机的滚筒洗衣机智能控制系统设计
  • 简述多模态学习中,对齐、融合和表示
  • Kotlin 进阶函数式编程技巧
  • 操作系统——内存映射文件(王道视频p57)
  • 王道p18 07.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。(c语言代码实现)
  • 2024最新mac电脑清理垃圾的软件有哪些?
  • 2023年【山东省安全员C证】考试技巧及山东省安全员C证模拟试题
  • 2024最新免费的mac电脑清理垃圾的软件有哪些?
  • linux下sqlplus登录oracle显示问号处理办法
  • Git 删除本地和远程分支
  • Selenium元素定位之页面检测技巧
  • C# 文件 文件夹 解除占用
  • 数据库 存储引擎
  • 操作系统复习(2)进程管理
  • 通过51单片机控制28byj48步进电机按角度正反转旋转
  • 二十三种设计模式全面解析-装饰器模式的高级应用:打造灵活可扩展的通知系统
  • 使用脚本整合指定文件/文件夹,执行定制化 ESLint 命令