统计得分小于 K 的子数组数目

简介: 🎈每天进行一道算法题目练习,今天的题目是“统计得分小于 K 的子数组数目”,一起来了解一下滑动窗口吧。

说在前面

🎈每天进行一道算法题目练习,今天的题目是“统计得分小于 K 的子数组数目”,一起来了解一下滑动窗口吧。

问题描述

一个数字的 分数 定义为数组之和 乘以 数组的长度。

比方说,[1, 2, 3, 4, 5] 的分数为 (1 + 2 + 3 + 4 + 5) * 5 = 75 。
给你一个正整数数组 nums 和一个整数 k ,请你返回 nums 中分数 严格小于 k 的 非空整数子数组数目。

子数组 是数组中的一个连续元素序列。

示例 1:

输入: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 。

示例 2:

输入:nums = [1,1,1], k = 5
输出:5
解释:
除了 [1,1,1] 以外每个子数组分数都小于 5 。
[1,1,1] 分数为 (1 + 1 + 1) * 3 = 9 ,大于 5 。
所以总共有 5 个子数组得分小于 5 。

提示:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
1 <= k <= 10^15

思路分析

首先我们应该要先了解一下题意,结合题目描述和例子分析,我们可以得出以下几点:

  • 1、子数组应该为连续的数组;
  • 2、子数组的分数等于子数组元素和乘于子数组长度;
  • 3、子数组的分数 严格小于 k。

这道题目的数据量为10^5,所以使用暴力枚举所有的子数组显然是不可以的,这道题目我们可以使用滑动窗口来进行解题。\
维护一个分数小于k的区间窗口及区间的分数,不断向右扩展,当区间分数大于k时,计算当前左端点可以组成的子数组数量并缩短区间,向前移动区间的左端点。

image.png

具体步骤如下:

  • 1、向右扩展窗口区间

我们可以使用一重循环来遍历数组,遍历到的位置即为当前窗口区间的右端点。扩展的同时计算当前区间的分数,分数大于等于k时需要缩小窗口区间,即将左端点前移。

for(let i = 0; i < nums.length; i++){
    sum += nums[i];
    while(sum * (i - l + 1) >= k){
        //左端点前移
    }
}
  • 2、向右缩小窗口区间

当分数大于等于k时需要缩小窗口区间,即将左端点前移,直到分数小于k时停止移动左端点,继续扩展右端点。

while(sum * (i - l + 1) >= k){
    sum -= nums[l];
    res += (i - l);
    l++;
}
  • 3、遍历完计算最后区间的子数组数量

遍历完之后我们还需要加上窗口区间的子数组数量。

while(nums.length - l > 0){
    res += (nums.length - l);
    l++;
}

AC代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
 var countSubarrays = function(nums, k) {
    let l = 0;
    let sum = 0,res = 0;
    for(let i = 0; i < nums.length; i++){
        sum += nums[i];
        while(sum * (i - l + 1) >= k){
            sum -= nums[l];
            res += (i - l);
            l++;
        }
    }
    while(nums.length - l > 0){
        res += (nums.length - l);
        l++;
    }
    return res;
};

说在后面

🎉这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。

image.png

目录
相关文章
|
应用服务中间件 索引 nginx
生产环境ES查询延迟排查
最近经常收到业务方配置的ES查询延迟告警,同样的请求手动在Kibana控制台执行只需几十毫秒就返回结果。受影响的整个链路情况如下,php应用程序通过部署在ES集群各节点上的nginx访问ES请求查询数据。
5718 0
|
NoSQL MongoDB 数据库
MongoDB 更新文档
10月更文挑战第14天
275 2
|
存储 NoSQL Linux
《探索 Linux 命令:systemd-coredumpctl》
**《systemd-coredumpctl概览》** `systemd-coredumpctl`, Linux中管理&分析core dump的利器。集中管控systemd生成的转储,详述crash细节。用`--list`查看所有转储,`--info &lt;ID&gt;`深入单一转储。需注意权限、存储管理,配gdb深化分析。精通此命令,加速问题诊断。#LinuxTips #CoreDumpAnalysis
|
Linux 网络安全
CentOS7关闭防火墙
CentOS7关闭防火墙
1168 0
CentOS7关闭防火墙
|
Kubernetes 数据可视化 jenkins
可视化 Tekton 组件 Tekton Dashboard
Tekton Dashboard 使用指南。
4488 0
可视化 Tekton 组件 Tekton Dashboard
|
关系型数据库 MySQL 数据安全/隐私保护
windows查看自己安装的Mysql版本
windows查看自己安装的Mysql版本
windows查看自己安装的Mysql版本
|
设计模式 存储 API
游戏服务器架构:网络服务器端程序线程划分
游戏服务器架构:网络服务器端程序线程划分
|
C#
【WPF】使用Popup控件做浮窗/提示框
原文:【WPF】使用Popup控件做浮窗/提示框 需求:当鼠标移入某个区域时,弹出一个浮窗,以便用户进行下一步操作。 效果如下图: 当鼠标移入左上角的【多选显示】框内,出现下面的浮窗(悬浮在原UI之上)。
4766 0
|
数据采集 运维 Ubuntu
使用kettle进行数据清洗
使用kettle进行数据清洗
使用kettle进行数据清洗
|
Web App开发 编解码 移动开发
秒懂流媒体协议 RTMP 与 RTSP
RTMP 与 RTSP 是比较常见的两种流媒体协议,那么什么是RTMP?什么是RTSP?它们两之间有什么区别?使用的时候应该如何选择?
2327 1
秒懂流媒体协议 RTMP 与 RTSP