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

LeetCode 2302 统计得分小于K的子数组数目(滑动窗口)

先给出示例吧

输入:nums = [2,1,4,3,5], k = 10
输出:6
解释:
有 6 个子数组的分数小于 10 :
- [2] 分数为 2 * 1 = 2 。
- [1] 分数为 1 * 1 = 1 。
- [4] 分数为 4 * 1 = 4 。
- [3] 分数为 3 * 1 = 3 。 
- [5] 分数为 5 * 1 = 5 。
- [2,1] 分数为 (2 + 1) * 2 = 6 。
注意,子数组 [1,4] 和 [4,3,5] 不符合要求,因为它们的分数分别为 10 和 36,但我们要求子数组 的分数严格小于 10 。

这还只是我优化后的思路,本来我是借助二维数组去维护其前缀和的长度的,所以代码一开始的复杂程度可想而知

对于本题其实就是一个前缀和加滑动窗口的思想,平时按照我这个思想去写的话完全没有问题,一开始我也是分不清滑动窗口和暴力,如下面的样例所示,一开始的解决我还是按照传统意义上的双循环遍历暴力解决,所以复杂度还是o(n*n)

class Solution {public long countSubarrays(int[] nums, long k) {int n = nums.length;// int number = (n+1)*n/2;int[] s = new int[n+1];// int[][] ans = new int[n + 1][n + 1];// 计算前缀和数组for (int i = 1; i <= n; i++) {s[i] = s[i - 1] + nums[i-1];}// int key=1;long total = 0;for(int l=1;l<=n;l++){int r = l;while(r<=n){int sum = s[r]-s[l-1];// ans[r-l+1][key] = sum;if(sum*(r-l+1) < k) total++;r++;}// key++;}// for(int i=1;i<=n;i++){//     for(int j=1;j<=n;j++){//         // System.out.println("ans[i][j]:"+ans[i][j]+",i:"+i+",j:"+j);//         if(ans[i][j]!=0&&(ans[i][j]*i)<k) total++;//     }// }return total;}
}

无论怎么优化依旧还超时过不了关,这是由于在我的遍历逻辑中还是去固定了左节点,然后一一遍历,这样会导致时间复杂度过高,也就当然会超时了。而滑动窗口的根本思想是外循环右扩展,内循环左收缩,并且r和l都不需要再一一初始化,保持更新即可。
其实最难的应该就是找到最简单的对应关系能联系到题目之中。

class Solution {public long countSubarrays(int[] nums, long k) {int n = nums.length;long total = 0;long sum = 0;int r = 0;for (int l = 0; l < n; l++) {while (r < n && (sum + nums[r]) * (r - l + 1) < k) {sum += nums[r];r++;}total += r - l;sum -= nums[l];}return total;}
}

我还是解释一下题解给的答案

题解的答案很简单就是将我上述的前缀和与滑动窗口结合到了一起,说是简单,但还是很难想到的,因为大多数人的思维都是单向的解决问题的思维,如我一般就是蹦着解决目的去的,并且过程也很符合题目的描述,扯远了,对于该题解,举个例子

示例[1,2,3,4,5] k=10
第一遍遍历 1*1<10 符合
第二遍遍历(1+2)*2<10符合
第三遍遍历(1+2+3)*3>=10不符合 此时r=2并记录下total+=r-l=2 将sum的值更新为2
第四遍遍历(2+3)*2>=10不符合 此时r=2 并再次记录下total+=r-l=3 将sum的值更新为2-2=0
第五遍遍历3*1<10 符合 此时r=2,l=2
第六遍遍历(3+4)*2>=10 不符合 此时r=3,l=2 并再次记录下total+=r-l=4 将sum的值更新为3-3=0;
依次往后继续遍历

所以说这就是该代码滑动窗口设计的秒的地方,没有任何瑕疵的遍历完一个数组并得到符合条件的子数组。

相关文章:

  • “连接世界的桥梁:深入理解计算机网络应用层”
  • 第十六届蓝桥杯 2025 C/C++组 脉冲强度之和
  • Leetcode 3533. Concatenated Divisibility
  • python中 str.strip() 是什么意思
  • CPU 空转解析
  • Spring Cloud 项目中优雅地传递用户信息:基于 Gateway + ThreadLocal 的用户上下文方案
  • oracle 批量查询每张表的数据量
  • 基于STM32、HAL库的AT88SC0104CA安全验证及加密芯片驱动程序设计
  • Linux/AndroidOS中进程间的通信线程间的同步 - 管道和FIFO
  • PyTorch实际上是按照**行优先(Row-Major)**的方式存储数据
  • 公路安全知识竞赛主持稿串词
  • Vim 中替换字符或文本
  • 无锡哲讯科技:SAP财务系统——赋能企业智慧财务管理
  • DeepSeek主动学习系统:低质量数据炼金术的工程化实践
  • SpringBoot Actuator未授权访问漏洞的全面解析与解决方案
  • 2025年欧洲西南部大停电
  • 顺序结构双链表的实现
  • Docker 容器双网卡访问物理雷达网络教程
  • 阿里云 CentOS YUM 源配置指南
  • 自动化立库/AGV物流仿真详细步骤
  • 顺利撤离空间站,神十九乘组踏上回家之旅
  • 运动健康|不同能力跑者,跑步前后营养补给差别这么大?
  • 北京动物园:大熊猫“萌兰”没有参加日本大阪世博会的计划
  • 专访丨青年作家杜梨:以动物的视角去观察这个世界
  • 视频丨伊朗港口爆炸事件灭火工作已完成80%
  • 2025厦门体育产业采风活动圆满举行