【队列】最大值减去最小值小于等于num的子数组数量
摘自《程序员代码面试指南》
题目:
给定数组 arr 和整数 num, 共返回有多少个⼦数组满⾜如下情况:
max(arr[i...j]) - min(arr[i...j]) <= num
max(arr[i...j])表示⼦数组 arr[i...j]中的最⼤值,min(arr[i...j])表示⼦数组arr[i...j]中的最小值。
题解:
区间最大最小值,立刻联想到单调栈(双端队列),不过稍微麻烦一些,需要在此基础上总结一些规律。
如果⼦数组 arr[i..j]满⾜条件, 即 max(arr[í.._i])-min(arr[i..j])<=num, 那么 arr[i..j]中的每⼀个⼦数组, 即 arr[k..l](i<=k<=|<=j)都满⾜条件 我们以⼦数组 arr[i..j-1]为例说明, arr[i..j-1]最⼤值只可能⼩于或等于arr[i..j]的最大值, arr[i..j-1]最小值只可能大于或等于 arr[i..j]的最小值, 所以 arr[i..j-|]必然满⾜条件, 同理, arr[i..j]中的每⼀个⼦数组都满⾜条件
如果⼦数组 arr[i..j]不 满⾜条件, 那 么 所有 包含 arr[i..j]的 ⼦数组, 即arr[k..l](k<=i<=j<=|)都不满⾜条件. 证明 过程同 第 ⼀个结论
也就是说,此问题还满足一个性质,那就是可以根据两端的下标范围确定满足条件的子数组个数,这一点很重要
Solution
#include <iostream>
#include <vector>
#include <deque> using namespace std; int maxMatchedArray(vector<int> &nums, int num){
deque<int> qmax, qmin;
int n = nums.size();
int res = ;
int i = , j = ;
while (i < n){
while (j < n){
while (!qmin.empty() && nums[qmin.back()] >= nums[j])
qmin.pop_back();
qmin.push_back(j);
while (!qmax.empty() && nums[qmax.back()] <= nums[j])
qmax.pop_back();
qmax.push_back(j);
if (nums[qmax.front()] - nums[qmin.front()] > num)
break;
++j;
}
if (qmin.front() == i)
qmin.pop_front();
if (qmax.front() == i)
qmax.pop_front();
res += j - i; //所有以arr[i]作为第一个元素的子数组,满足条件的数量为 j - i 个
++i;
}
return res;
} int main(){
vector<int> v{ ,,,,,,,,,};
int n = ;
cout << maxMatchedArray(v, n) << endl;
system("pause");
return ;
}
【队列】最大值减去最小值小于等于num的子数组数量的更多相关文章
- 栈和队列----最大值减去最小值小于等于num的子数组的数量
最大值减去最小值小于等于num的子数组的数量 给定数组arr和整数 num,共返回有多少个数组满足下列情况: max(arr[i..j])-min(arr[i..j])<=num.其中max(a ...
- 最大值减去最小值小于或等于num的子数组数量
[说明]: 本文是左程云老师所著的<程序员面试代码指南>第一章中“最大值减去最小值小于或等于num的子数组数量”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路, ...
- [程序员代码面试指南]栈和队列-最大值减去最小值 小于或等于num 的子数组的数量(单调队列)
题目 给定数组arr和整数num,求数组的子数组中有多少个的满足"最大值减去最小值<=num". 解题思路 分析题目,有结论: 如果数组arr[i...j]满足条件,则它的每 ...
- 左神算法书籍《程序员代码面试指南》——1_10最大值减去最小值小于或等于num的子数组数量
[题目]给定数组arr和整数num,共返回有多少个子数组满足如下情况:max(arr[i.j]) - min(arr[i.j]) <= num max(arfi.j])表示子数组ar[ij]中的 ...
- 牛客 最大值减去最小值小于或等于 num 的子数组数量
题目链接:https://www.nowcoder.com/practice/5fe02eb175974e18b9a546812a17428e?tpId=101&tqId=33086& ...
- 算法进阶面试题02——BFPRT算法、找出最大/小的K个数、双向队列、生成窗口最大值数组、最大值减最小值小于或等于num的子数组数量、介绍单调栈结构(找出临近的最大数)
第二课主要介绍第一课余下的BFPRT算法和第二课部分内容 1.BFPRT算法详解与应用 找到第K小或者第K大的数. 普通做法:先通过堆排序然后取,是n*logn的代价. // O(N*logK) pu ...
- 《程序员代码面试指南》第一章 栈和队列 最大值减去最小值小于或等于num的数量
题目 给定整数数组arr和整数num,共返回多少的数组满足如下情况 max(arr[i...j]) - min(arr[i...j]) <= num max(arr[i...j])表示数组arr ...
- 算法总结之 最大值减去最小值或等于num的子数组数量
给定数组arr和整数num,共返回有多少个子数组满足 <= num 数组长度N 时间复杂度O(N) package TT; import java.util.LinkedList; pu ...
- [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 ...
随机推荐
- poj1061(extendgcd)
看完题目后,题目要求: 设时间为t (x+mt)%L = (y+nt)%L ( x-y + (m-n)*t )= k*L (k是整数,可为负) 然后就是经典的 xa+yb=c 求解x,y的经典题目了. ...
- EasyNVR无插件直播服务器软件使用详情功能-通道配置Excel
背景需求 使用EasyNVR的用户都有知道,由于EasyNVR是将设备与EasyNVR的通道进行绑定的,因此EasyNVR是通过手动的通道配置来进行设备接入的,这样可以做到将设备的和通道对应的接入.但 ...
- Storm编程模型及Worker通信机制
1.编程模型 2.Worker通信机制
- 九度OJ 1351:数组中只出现一次的数字 (位运算)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3098 解决:906 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个 ...
- 九度OJ 1188:约瑟夫环 (约瑟夫环)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1891 解决:817 题目描述: N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的人再从1.2.3 ...
- MySQL合并多行
select id,group_concat(re_id order by re_id separator ",") as re_idfrom tablenamegroup by ...
- 洛谷 P2486 [SDOI2011]染色
题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例#1: 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C ...
- go语言之并发编程一
Go语言最大的优势就在于并发编程.Go语言的关键字go就是开启并发编程也就是goroutine的唯一途径.一条go语句以为着一个函数或方法的并发执行.Go语句是由go关键字和表达式组成.比如下面的这种 ...
- Linux c编程:I/O多路复用之select
一般我们在写socet程序的时候调用的accept,recv等操作都是阻塞型的.意思就是如果我们一直收不到数据那么则会被阻塞.所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待 ...
- java基础入门之数组循环初始化
/* Name:数组循环化 Power by Stuart Date:2015-4-23 */public class ArrayTest02{ public static void main (St ...