难度:中等

题目描述

We are given an array A of positive integers, and two positive integers L and R (L <= R).

Return the number of (contiguous, non-empty) subarrays such that the value of the maximum array element in that subarray is at least L and at most R.

Example :
Input:
A = [2, 1, 4, 3]
L = 2
R = 3
Output: 3

Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3].

Note:
L, R and A[i] will be an integer in the range [0,109][0, 10^9][0,109].
The length of A will be in the range of [1,50000][1, 50000][1,50000].

简单说就是给定一个数组,和一个区间[L,R][L,R][L,R],问:这个数组的子数组的最大值在这个给定区间的数组个数是多少。

需要注意子数组和子集的概念不同,子数组必须是连续的。

题解

解法一:暴力搜索

首先拿到题目,我们可以先从暴力搜索算法开始做起,然后逐步优化。

class Solution {public:int numSubarrayBoundedMax(vector<int>& A, int L, int R) {int res = 0;// 暴力搜索// 以A[i]开头的子数组for (int i = 0; i < A.size(); i++) {int curMax = INT_MIN;for (int j = i; j < A.size(); j++) {curMax = max(curMax, A[j]);// 不做优化的暴力搜索if (curMax <= R && curMax >= L) {res++;}}}return res;}
};

这是不做任何优化的暴力搜索解法,也即,循环计算以A[i]开头的子数组是否满足需求,并在循环过程中维护一个当前最大值curMax,看它是否在给定区间。

这个是过不了OJ的,因为实践复杂度O(n2)O(n^2)O(n2),我们可以稍稍做一些搜索剪枝,比如在外层循环,如果A[i] > R,那么本次循环就可以作废了,因为这里的子数组全是以A[i]开头的,用continue进入下一层循环。

在内层数组,再判断curMax是否大于R,如果超过则内层循环直接结束。为什么呢?以A[i]开头的子数组,然后在中间遇到了不满足的,后面就不用再继续循环下去了,因为这个不满足的数字是子数组中间的元素。

加上两个剪枝,可以OJ,但是效果不是很好。

class Solution {public:int numSubarrayBoundedMax(vector<int>& A, int L, int R) {int res = 0;// 暴力搜索// 以A[i]开头的子数组for (int i = 0; i < A.size(); i++) {int curMax = INT_MIN;// 外层搜索剪枝if (A[i] > R) {continue; // 跳过本轮循环}for (int j = i; j < A.size(); j++) {curMax = max(curMax, A[j]);if (curMax > R) break; // 内层搜索剪枝if (curMax >= L) {res++;}}}return res;}
};


解法二:等差数列法

class Solution {public:int count(vector<int>& A, int upper) {int res = 0, cur = 0;for (auto x : A) {cur = (x <= upper) ? cur + 1 : 0;res += cur;}return res;}int numSubarrayBoundedMax(vector<int>& A, int L, int R) {return count(A, R) - count(A, L-1);}
};

直接看这个算法的代码是会很懵的,除非手动跟踪一下看看。

总体思路是,设定一个函数,计算子数组最大元素在(−∞,upperBound](-\infty,upperBound](−∞,upperBound]内的子数组个数,看起来像不像是概率分布的定义~

我们假定这个上界大于等于原数组的最大值,我们来计算一下子数组的个数规律。

就拿[2,1,4,3][2,1,4,3][2,1,4,3]来举例子,假定上界是4,则区间是(−∞,4](-\infty,4](−∞,4]。

  • 遍历到2时,满足条件的子数组有[2][2][2],共1个;
  • 遍历到1时,满足条件的子数组有[2],[1],[2,1][2],[1],[2,1][2],[1],[2,1]共3个;
  • 遍历到4时,满足条件的子数组有[2],[1],[4],[2,1],[1,4],[2,1,4][2],[1],[4],[2,1],[1,4],[2,1,4][2],[1],[4],[2,1],[1,4],[2,1,4]共6个;

然后遍历到3时,满足条件的共有10个;满足条件的子数组的个数 = n(n+1)2\frac{n(n+1)}{2}2n(n+1)​,是个等差为1的等差数列的求和。

为什么要说这个呢,是因为,在遇到不符合的元素前,计算符合条件的子数组的数量就是这个方式;然后在遇到不符合的了呢,就需要中断这个累计过程(将cur重置为0),重新开始这个等差数列的累计过程。

还有一种写法如下:

class Solution {public:int numSubarrayBoundedMax(vector<int>& A, int L, int R) {int res = 0, left = -1, right = -1;for (int i = 0; i < A.size(); ++i) {if (A[i] > R) left = i;if (A[i] >= L) right = i;res += right - left;}return res;}
};

本质上和上面的写法相似。

END.

【Leetcode 795】Number of Subarrays with Bounded Maximum相关推荐

  1. LeetCode 795. Number of Subarrays with Bounded Maximum

    问题链接 LeetCode 795 题目解析 给定一个数组A,左右范围L.R.求子数组的数量,要求:子数组最大值在L.R之间. 解题思路 子数组必须连续,利用最大值R对数组进行分段,设定变量 left ...

  2. leetcode 795. Number of Subarrays with Bounded Maximum | 795. 区间子数组个数(Java)

    题目 https://leetcode.com/problems/number-of-subarrays-with-bounded-maximum/ 题解 一看数据规模,这题只能 O(1) 乍一看,以 ...

  3. 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符

    题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...

  4. 【LeetCode - 32】最长有效括号

    给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度. 示例 1: 输入:s = "(()" 输出:2 解释:最长有效括号子串是 " ...

  5. 【LeetCode题解】二叉树的遍历

    我准备开始一个新系列[LeetCode题解],用来记录刷题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有两个节点--左孩 ...

  6. 如何给柱状图柱子添加阴影_【LeetCode日记】84. 柱状图中最大的矩形

    题目描述 ` 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度为 1,给 ...

  7. 【LeetCode笔记】253. 会议室 II(Java、偏数学)

    文章目录 题目描述 思路 && 代码 计划里 hot 100 + 剑指Offer 的题目中唯一一道会员题,同时也是最后一道没写的题,刚好今天 leetcode 发了一天会员可以写上-简 ...

  8. 【LeetCode笔记】301. 删除无效的括号(Java、DFS、字符串)

    文章目录 题目描述 思路 && 代码 二刷 题目描述 [所有可能结果]-> [暴力DFS] 思路 && 代码 代码比较长,但是总体思路很清晰. 剪枝:舍弃左括号. ...

  9. 【LeetCode 871】 Minimum Number of Refueling Stops

    题目描述 A car travels from a starting position to a destination which is target miles east of the start ...

最新文章

  1. 逻辑回归:确定一个人是否年收入超过5万美元
  2. vue脚手架搭建配置试调地址和端口号_全栈的自我修养: 002使用@vue/cli进行vue环境搭建 (使用Vue,SpringBoot,Flask完成前后端分离)...
  3. TCP传输过程中丢包问题
  4. Hibernate SessionFactory
  5. 写给人类的机器学习 2.2 监督学习 II
  6. 抛弃百度UMEditor,拥抱summernote (解决上传文件又慢又卡的问题)
  7. SMA2.92高频连接器的主要特点​
  8. 香港地图、行政区划地图辖区边界、沙田
  9. linux操作系统. 80188,Materials-Studio5.5在Linux服务器上安装与测算讨论 - 第一原理 - 小木虫 - 学术 科研 互动社区...
  10. Hibernate实战——双向N-N关联
  11. 在计算机桌面如何切换成大图标,win7系统桌面图标怎么设置大小 win7电脑桌面图标大小更改方法...
  12. Qmail 日志文件格式
  13. 梦想贩卖机v2版本1.0.69无限制版小程序源码{已修复助力和瀑布流问题}
  14. 安卓镜像刻录软件_安卓8.0开发者预览版镜像系统下载-Android O开发者预览版镜像官方正式版-东坡下载...
  15. TTY列下的tty?和pts/1,pts/1,pts/2代表的含义
  16. gb和gib的区别_KB/KiB,MB/MiB,GB/GiB,它们有区别吗?
  17. Mac全选,剪切和复制粘贴
  18. GH60--来自geekhack的超强玩具
  19. 计算机设置更改被锁定怎么办,处理win7电脑中IE主页一直被锁定修改的问题
  20. 拆解 米家扫地机器人_米家扫地机器人拆机报告20161215.pptx

热门文章

  1. 【ROS学习笔记】(十)ROS中的坐标系管理系统
  2. 2345浏览器网址_清理流氓网站2345.com劫持浏览器
  3. java服务器项目,java项目服务器部署
  4. 计算机组成原理 陈泽,计算机组成原理 课程设计计算机组成原理 课程设计.doc...
  5. mysql异机备份脚本_mysqldump使用rsync异地全量备份数据库
  6. java ftp连接成功 上传失败_ftp自动上传工具,如何设置及配置ftp自动上传工具
  7. c 语言矩阵求逆算法,矩阵的逆 C 语言 算法一
  8. php 遍历目录函数,PHP 遍历指定目录所有文件函数的简单示例(可指定文件类型)...
  9. matlab中svm testacc参数,使用Matlab进行交叉验证的多类SVM的完整示例
  10. Python数据结构与算法(1.4)——Python基础之控制结构