作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/number-of-subarrays-with-bounded-maximum/description/

题目描述

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, 10^9].
  • The length of A will be in the range of [1, 50000].

题目大意

给定了一个数组和L,R两个数字。现在我们要求在这个数组中能有多少个连续的子数组,使得这个子数组的最大值在L和R之间。

解题方法

动态规划

第一感觉是dfs,但是看了下A的长度范围发现基本只能用O(n)的算法了,因此只能使用dp去求了。

我们设定dp数组,其dp[i]的含义是以A[i]为结尾的子数组中满足题目要求的数组个数。所以我们在这个定义的基础上,能得到下面的关系式:

  1. A[i] < L
    这个情况,以A[i]为结尾的子数组的最大值没有改变,因此dp[i] = dp[i - 1]
  2. A[i] > R
    此时,以A[i]为结尾的子数组的最大值已经大于了R,所以dp[i] = 0.把这个位置设定为新的开始,记录该位置为prev.
  3. L <= A[i] <= R
    从prev到i之间的任意起始位置到i的子数组都满足题目条件,因此dp[i] = i - prev.

根据上面的关系式可以写出代码,最后的结果是整个dp之和。

该代码的时间复杂度是O(n),空间复杂度也是O(n)。

代码如下:

class Solution(object):
def numSubarrayBoundedMax(self, A, L, R):
"""
:type A: List[int]
:type L: int
:type R: int
:rtype: int
"""
if not A: return 0
dp = [0] * len(A)
prev = -1
for i, a in enumerate(A):
if a < L and i > 0:
dp[i] = dp[i - 1]
elif a > R:
dp[i] = 0
prev = i
elif L <= a <= R:
dp[i] = i - prev
return sum(dp)

因为dp[i]只和dp[i-1]有关,所以可以把空间复杂度将为O(1)。

class Solution(object):
def numSubarrayBoundedMax(self, A, L, R):
"""
:type A: List[int]
:type L: int
:type R: int
:rtype: int
"""
dp = 0
res = 0
prev = -1
for i, a in enumerate(A):
if a < L and i > 0:
res += dp
elif a > R:
dp = 0
prev = i
elif L <= a <= R:
dp = i - prev
res += dp
return res

暴力搜索+剪枝

如果二重循环可以求出每个数组,但是肯定会超时。不过,如果我们考虑一下剪枝,外层循环里面当前值大于R的时候,就移到下一个位置;内层循环里面,如果当前值大于R,那么后面的全部都不满足,所以直接break掉。这样就能过了!!

class Solution {
public:
int numSubarrayBoundedMax(vector<int>& A, int L, int R) {
const int N = A.size();
int res = 0;
for (int i = 0; i < N; ++i) {
if (A[i] > R) continue;
int curMax = INT_MIN;
for (int j = i; j < N; ++j) {
curMax = max(curMax, A[j]);
if (curMax > R) break;
if (curMax >= L) ++res;
}
}
return res;
}
};

线性遍历

定一个函数count():数组中最大值小于等于bound的子数组个数。所以,我们的最终结果是就是count - count(L-1)。

count函数很好设计,因为只需要线性遍历一次,就知道了。每次遍历的时候,如果当前的值小于等于bound,那么就等于在前面的子数组上又加上了一个新的数组。所以我们需要一个变量来保存前面的数组有多少个了。

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

我最初的想法其实就是双指针,类似虫取法。虽然想法简单,但是如果思路不够清除,根本写不出来。下面就是这个虫取法求子数组的方法。

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

参考资料:
http://www.cnblogs.com/grandyang/p/9237967.html

日期

2018 年 9 月 14 日 —— 现在需要的还是夯实基础,算法和理论
2018 年 12 月 16 日 —— 周赛好难

【LeetCode】795. Number of Subarrays with Bounded Maximum 解题报告(Python & C++)的更多相关文章

  1. LeetCode 795. Number of Subarrays with Bounded Maximum

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

  2. 795. Number of Subarrays with Bounded Maximum

    数学的方式 是对于所有的字符分成简单的三类 0 小于 L 1 LR 之间 2 大于R 也就是再求 不包含 2 但是包含1 的子数组个数 不包含2的子数组个数好求 对于连续的相邻的n个 非2类数 就有 ...

  3. [LeetCode] Number of Subarrays with Bounded Maximum 有界限最大值的子数组数量

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

  4. 74th LeetCode Weekly Contest Number of Subarrays with Bounded Maximum

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

  5. [Swift]LeetCode795. 区间子数组个数 | Number of Subarrays with Bounded Maximum

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

  6. LeetCode 806 Number of Lines To Write String 解题报告

    题目要求 We are to write the letters of a given string S, from left to right into lines. Each line has m ...

  7. 【LeetCode】26. Remove Duplicates from Sorted Array 解题报告(Python&C++&Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 日期 [LeetCode] https:// ...

  8. 【LeetCode】450. Delete Node in a BST 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 日期 题目地址:https://leetcode ...

  9. 【LeetCode】452. Minimum Number of Arrows to Burst Balloons 解题报告(Python)

    [LeetCode]452. Minimum Number of Arrows to Burst Balloons 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https ...

随机推荐

  1. sersync+rsync进行数据同步

    一:环境 操作系统环境:redhat6.6 内核版本:2.6.32-358.el6.x86_64 rsync server:192.168.2.3(部署rsync server) rsync clie ...

  2. shell 脚本的基本定义

    注意不能有控制,指令之间 [1]shell脚本的基础知识 (1)shell脚本的本质 编译型语言 解释型语言 shell脚本语言是解释型语言 shell脚本的本质 shell命令的有序集合 (2)sh ...

  3. Shell 输出第五行的内容

    目录 Shell 输出第五行的内容 题目 题解-awk 题解-sed Shell 输出第五行的内容 题目 写一个 bash脚本以输出一个文本文件 nowcoder.txt 中第5行的内容. 示例: 假 ...

  4. 『学了就忘』Linux启动引导与修复 — 68、Linux系统运行级别

    目录 1.Linux系统运行级别介绍 2.查看运行级别 3.修改当前系统的运行级别 4.系统默认运行级别 5./etc/rc.d/rc.local文件说明 1.Linux系统运行级别介绍 Linux默 ...

  5. Oracle—数据库名、数据库实例名、数据库域名、数据库服务名的区别

    Oracle-数据库名.数据库实例名.数据库域名.数据库服务名的区别 一.数据库名 1.什么是数据库名       数据库名就是一个数据库的标识,就像人的身份证号一样.他用参数DB_NAME表示,如果 ...

  6. Linux学习 - shell脚本执行

    一.shell概述 shell是一个命令行解释器,为用户提供一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动.挂起.停止甚至是编写一些程序 shell还是一个功能强 ...

  7. Linux学习 - ACL权限

    一.ACL权限简介 ACL权限是为了防止权限不够用的情况,一般的权限有所有者.所属组.其他人这三种,当这三种满足不了我们的需求的时候就可以使用ACL权限 二.ACL权限开启 1 查看当前系统分区 df ...

  8. zabbix之微信报警

    #:先在企业微信注册一个企业微信号 #:注册好之后,进入微信 #:测试一下 #:获取access_token #:开始获取 #:获取 #:在server端安装pip root@ubuntu:~# ap ...

  9. sql优化的8种方式 (下)

    五.条件列表值如果连续使用between替代in        六.无重复记录的结果集使用union all合并 MySQL数据库中使用union或union all运算符将一个或多个列数相同的查询结 ...

  10. MyBatis通过注解实现映射中的嵌套语句和嵌套结果

    案例描述:查看订单或购物车订单信息的同时查询出该订单中所有书籍的信息. 一.嵌套语句 @Select("select* from shopcart where shopcartid = #{ ...