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

【单调向量 单调栈】3676. 碗子数组的数目|1848

单调向量

C++单调栈

3676. 碗子数组的数目

给你一个整数数组 nums,包含 互不相同 的元素。
nums 的一个子数组 nums[l…r] 被称为 碗(bowl),如果它满足以下条件:
子数组的长度至少为 3。也就是说,r - l + 1 >= 3。
其两端元素的 最小值 严格大于 中间所有元素的 最大值。也就是说,min(nums[l], nums[r]) > max(nums[l + 1], …, nums[r - 1])。
返回 nums 中 碗 子数组的数量。
子数组 是数组中连续的元素序列。
示例 1:
输入: nums = [2,5,3,1,4]
输出: 2
解释:
碗子数组是 [3, 1, 4] 和 [5, 3, 1, 4]。
[3, 1, 4] 是一个碗,因为 min(3, 4) = 3 > max(1) = 1。
[5, 3, 1, 4] 是一个碗,因为 min(5, 4) = 4 > max(3, 1) = 3。
示例 2:
输入: nums = [5,1,2,3,4]
输出: 3
解释:
碗子数组是 [5, 1, 2]、[5, 1, 2, 3] 和 [5, 1, 2, 3, 4]。
示例 3:
输入: nums = [1000000000,999999999,999999998]
输出: 0
解释:
没有子数组是碗。
提示:
3 < = n u m s . l e n g t h < = 1 0 5 3 <= nums.length <= 10^5 3<=nums.length<=105
1 < = n u m s [ i ] < = 1 0 9 1 <= nums[i] <= 10^9 1<=nums[i]<=109
nums 由不同的元素组成。

单调向量

r 从2到大枚举,v记录所有可能的left。
性质一:如果nums[i]< nums[r-1],则任意r1 \ge r,[i…r1]都不是碗子数组。故nums[i]可以永久被删除。
性质二:按性质一删除后,v降序。
性质三:v[i]对应k1,v[i+1]对应k2,则 ∀ k 1 ≤ k ≤ k 2 \forall k1\le k \le k2 k1kk2,nums[k] < nums[k2] < nums[k1]。
nums[r-1]按性质一入向量。如果nums[r] < nums[r-1],则 ∀ l e f t \forall left left,nums[left ⋯ r \cdots r r]都不是碗子数组。否则:
it 是v中指向第一个小于nums[r]的迭代器。如果it不是起始迭代器,则–it。
v.end()-it 就是 nums[left ⋯ r \cdots r r]都是碗子数组的数量。

核心代码

class Solution {public:long long bowlSubarrays(vector<int>& nums) {vector<int> v = { nums[0] };long long ans = 0;				for(int i = 2; i < nums.size();i++){while (v.size() && ( v.back()< nums[i-1])){v.pop_back();}if (nums[i - 1] < nums[i]) {auto it = lower_bound(v.begin(), v.end(), nums[i],greater<>());ans += v.end()-it;ans += (v.begin() != it);}v.emplace_back(nums[i-1]);}return ans;}};

单元测试

vector<int> nums;TEST_METHOD(TestMethod11){nums = { 2,5,3,1,4 };auto res = Solution().bowlSubarrays(nums);AssertEx(2LL, res);}TEST_METHOD(TestMethod12){nums = { 5,1,2,3,4 };auto res = Solution().bowlSubarrays(nums);AssertEx(3LL, res);}TEST_METHOD(TestMethod13){nums = { 1000000000,999999999,999999998 };auto res = Solution().bowlSubarrays(nums);AssertEx(0LL, res);}

单调栈

进一步优化。
性质四:如果nums[r]淘汰nums[left],则 ∀ k , n u m s [ l e f t ] > n u m s [ k ] \forall k,nums[left]>nums[k] k,nums[left]>nums[k],否则nums[k]会淘汰nums[left];nums[r]>nums[k],否则无法淘汰。
如果r - left+1 g e > 3 ge>3 ge>3 则是解。
如果v.back()存在,则nums[v.back() ⋯ \cdots r]也是碗子数组,且下标差 ≥ 3 \ge 3 3,也是碗子数组。
空间复杂度时间复杂度:都是O(n)。

核心代码

class Solution {public:long long bowlSubarrays(vector<int>& nums) {stack<int> sta;long long ans = 0;for (int i = 0; i < nums.size();i++) {while (sta.size() && (nums[sta.top()] < nums[i])){ans += (i - sta.top() + 1 >= 3);sta.pop();}if (sta.size()){ans += (i - sta.top() + 1 >= 3);}sta.emplace(i);}return ans;}};

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
员工说:技术至上,老板不信;投资人的代表说:技术至上,老板会信。
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

http://www.dtcms.com/a/490978.html

相关文章:

  • 【JUnit实战3_01】第一章:JUnit 起步
  • 公司门户网站该怎么做用模块做网站
  • 合肥网站定制公司宁波做网站公司哪家好
  • Banana Script,一个C99实现的,类JavaScript极简语法的脚本引擎
  • 14-机器学习与大模型开发数学教程-第1章 1-6 费马定理与极值判定
  • 写的网站怎么做接口php在网站上怎么做充值
  • nginx报400bad request 请求头过大异常处理
  • react+springboot云上部署
  • Google 地图类型
  • 免费网站做企业的网站都要准备什么
  • 网站建设往年的高考题免费看电视的网站有哪些
  • STM32N6 KEIL IDE 调试XIP 应用的一种方法 LAT1575
  • 大模型微调(二):使微调保持稳定的策略
  • 前端调优23大规则(Part 4)
  • SpringBoot-入门介绍
  • 如何推动AI技术在企业管理中的商业化落地?
  • 淘宝网站建设的策划书产品软文案例
  • 复制带随机指针的链表
  • Promise 与 async/await
  • win11 字体变宽问题
  • 最好的做网站机械加工网站色彩搭配
  • Pytorch Yolov11目标检测+Android部署 留贴记录
  • iis 发布网站 404archlinux+wordpress
  • leetcode 2598. 执行操作后的最大 MEX 中等
  • SuperMap iObject Java实现倾斜数据预处理
  • 逻辑方阵(Logical Square)解说
  • Vue与React中动态导入的原理及实现差异解析
  • 有一个网站自己做链接获取朋友位置传媒公司属于什么行业类型
  • 服饰类电商网站建设策划昆山vi设计
  • aben.co微端侧模型价格实惠的服务商