二分查找|前缀和|滑动窗口|2302:统计得分小于 K 的子数组数目

作者推荐

贪心算法LeetCode2071:你可以安排的最多任务数目

本文涉及的基础知识点

二分查找算法合集

题目

一个数组的 分数 定义为数组之和 乘以 数组的长度。
比方说,[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 <= 105
    1 <= nums[i] <= 105
    1 <= k <= 1015

二分查找、前缀和

代码

时间复杂度

O(nlogn)。枚举子数组起点,时间复杂度O(n);二分查找终点:时间复杂度O(logn)。

原理

寻找最后一个符合以下条件的vNumRight,故用左闭右开空间。vNumRight的取值范围是[vNumLeft,m_c],换成左闭右开空间是[vNumLeft,m_c+1)。nums[vNumLeft,vNumRight) 就是要判断的子数组。

核心代码

class Solution {
public:long long countSubarrays(vector<int>& nums, long long k) {m_c = nums.size();vector<long long> vPreSum = { 0 };for (const auto& n : nums){vPreSum.emplace_back(vPreSum.back() + n);}long long llRet = 0;for (int vNumLeft = 0; vNumLeft < m_c; vNumLeft++){//求最大的vNumRight,使得nums[vNumLeft,vNumRight)的得分小于k。左闭右开int left = vNumLeft, right = m_c + 1;while (right - left > 1){const auto mid = left + (right - left) / 2;if ((vPreSum[mid] - vPreSum[vNumLeft])*(mid-vNumLeft) < k){left = mid;}else{right = mid;}}llRet += left - vNumLeft;}return llRet;}int m_c;
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
vector nums;
long long k,res;
{
Solution slu;
nums = { 2, 1, 4, 3, 5 }, k = 10;
auto res = slu.countSubarrays(nums, k);
Assert(6LL, res);
}
{
Solution slu;
nums = { 1,1,1 }, k =5;
auto res = slu.countSubarrays(nums, k);
Assert(5LL, res);
}
{
Solution slu;
nums = { 9,5,3,8,4,7,2,7,4,5,4,9,1,4,8,10,8,10,4,7 }, k = 4;
auto res = slu.countSubarrays(nums, k);
Assert(3LL, res);
}
//CConsole::Out(res);
}

滑动窗口

时间复杂度O(n)

由于是正整数,所以子数组起点相同,终点越大,积分越大。相同的left,right不断增大。left增大,right不变或变大。left循环O(n)次,right也是。right总共循环了o(n),每次都是接着上次的right开始,没有重新开始。

代码

class Solution {
public:long long countSubarrays(vector<int>& nums, long long k) {m_c = nums.size();long long llSum = 0;long long llRet = 0;for (int left = 0,right=0; left < m_c; left++){//子数组nums[left,right)符合要求,且right是当前left的最大值while ((right < m_c) && ((llSum+nums[right]) * (right+1 - left) < k)){llSum += nums[right++];}llRet += right - left;llSum -= nums[left];}	return llRet;}int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业

。也就是我们常说的专业的人做专业的事。 |
|如果程序是一条龙,那算法就是他的是睛|

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/260069.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【带头学C++】----- 九、类和对象 ---- 9.10 C++设计模式之单例模式设计

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️麻烦您点个关注&#xff0c;不迷路❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目 录 9.10 C设计模式之单例模式设计 举例说明&#xff1a; 9.10 C设计模式之单例模式设计 看过我之前的文章的&#xff0c;简单讲解过C/Q…

Python:核心知识点整理大全8-笔记

目录 ​编辑 4.5 元组 4.5.1 定义元组 dimensions.py 4.5.2 遍历元组中的所有值 4.5.3 修改元组变量 4.6 设置代码格式 4.6.1 格式设置指南 4.6.2 缩进 4.6.3 行长 4.6.4 空行 4.6.5 其他格式设置指南 4.7 小结 第5章 if语句 5.1 一个简单示例 cars.py 5.2 条…

Kafka快速实战以及基本原理详解

文章目录 一、Kafka介绍为什么要用Kafka 二、Kafka快速上手实验环境单机服务体验 三、理解Kakfa的消息传递机制四、Kafka集群服务五、理解服务端的Topic、Partition和Broker七、Kafka集群的整体结构八、Kraft集群Kraft集群简介配置Kraft集群 一、Kafka介绍 ChatGPT对于Apache …

探索HarmonyOS开发—Slider滑动条组件

Slider Slider 滑块组件 Slider({min: 0, // 最小值max: 350, // 最大值value: 30, // 当前值step:10, // 滑动步长style:SliderStyle.OutSet, // Inset 滑块的位置direction:Axis.Horizontal, // Verticalreverse:false // 是否反向滑动 }) style属性可以控制滑块在整个滑块…

元宇宙vr党建云上实景展馆扩大党的影响力

随着科技的飞速发展&#xff0c;VR虚拟现实技术已经逐渐融入我们的日常生活&#xff0c;尤其在党建领域&#xff0c;VR数字党建展馆更是成为引领红色教育新风尚的重要载体。今天&#xff0c;就让我们一起探讨VR数字党建展馆如何提供沉浸式体验&#xff0c;助力党建工作创新升级…

使用STM32 HAL库进行GPIO控制的实例

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

通过误差改变控制的两种策略

如果反馈误差越来越大&#xff0c;需要改变调节方向以减小误差并实现更好的控制。以下是两种常见的调节方向改变的方法&#xff1a; PID控制器中的积分限制&#xff1a;在PID控制中&#xff0c;积分项可以用来减小稳态误差。然而&#xff0c;当反馈误差持续增大时&#xff0c;积…

28、pytest实战:获取多用户鉴权

前提 测试过程中有用户体系&#xff0c;例如包括管理员、商家、用户角色&#xff0c;不同测试用例需要使用不同角色来操作&#xff0c;操作权限根据用户的鉴权来判断实现。 技能点 建立全局变量文件&#xff0c;保存账号相关信息获取鉴权信息变为module级别fixture&#xff…

Kafka在微服务架构中的应用:实现高效通信与数据流动

微服务架构的兴起带来了分布式系统的复杂性&#xff0c;而Kafka作为一款强大的分布式消息系统&#xff0c;为微服务之间的通信和数据流动提供了理想的解决方案。本文将深入探讨Kafka在微服务架构中的应用&#xff0c;并通过丰富的示例代码&#xff0c;帮助大家更全面地理解和应…

鸿蒙开发—学习声明式UI

基本UI描述 ArkTS通过装饰器Component和Entry装饰struct关键字声明的数据结构&#xff0c;构成一个自定义组件。自定义组件中提供了一个build函数&#xff0c;开发者需在该函数内以链式调用的方式进行基本的UI描述&#xff0c;UI描述的方法请参考UI描述规范。 基本概念 stru…

UWB的matlab仿真源码

作品详细文章与下载链接 第一部分:TR-UWB信号的产生和调制 简介 该实践涉及使用 MATLAB 生成和调制 TR-UWB 信号。超宽带信号是一类在频谱中具有宽带而不是窄带的信号信号&#xff0c;具有时间宽度的脉冲产生它。在本次实践中,MATLAB 程序是开发用于生成基带 TR-UWB 信号,我们用…

关于idea2023创建项目时怎么使用jdk8

最近用idea创建项目时&#xff0c;发现java的版本只能选择17或22&#xff0c;springboot的版本只能选择3.2.0&#xff1a; 那么&#xff0c;如果我们要用jdk8和springboot2的话&#xff0c;那要怎么做呢&#xff1f; 不急&#xff0c;我们先点击create创建项目&#xff0c;然后…