每日一题 为了工作 2020 0312 第十题
/**
*
* 问题:
* 最大值减去最小值小于或等于num子数组的数量
* 给定数组arr和整数num,共返回有多少个子数组满足如下情况:
* 1.max(arr[i..j])-min(arr[i..j]) <= num
* 2.max(arr[i..j])表示子数组arr[i..j]中的最大值
* 3.min(arr[i..j])表示子数组arr[i..j]中的最小值
*
* 要求:
* 如果数组长度为N,请实现时间复杂度为O(N)的解法。
*
* 解答:
* 首先介绍普通的解法,找到arr的所有子数组,一共有O(N^2)个,然后对每一个子数组做遍历找到其中的最小值和最大值,这个过程
*的时间复杂度为O(N),然后看看这个子数组是否满足条件。统计其中所有满足条件的子数组数量即可。普通解法容易实现,但是时间复杂度为
*O(N^3),希望达到O(N)的时间复杂度需要使用双端队列。
*
* 生成两个双端队列qmax和qmin。当子数组为arr[i..j]时,qmax维护了窗口子数组arr[i..j]的最大值更新结构,qmin维护
*了窗口子数组arr[i..j]的最小值更新结构。
*当数子组arr[i..j]向右扩一个位置变成arr[i..j+1]时,qmax和qmin结构的更新代价的平均时间复杂度为O(1),并且可以再O(1)的
*时间内得到arr[i..j+1]的最大值和最小值。
*当子数组arr[i..j]向左扩一个位置变成arr[i+1..j]时,qmax和qmin结构的更新代价的平均时间复杂度为O(1),并且可以再O(1)的
*时间内得到arr[i+1..j]的最大值和最小值。
*
* 通过分析题目满足的条件,可以得到如下两个结论。
*
* 1.如果子数组arr[i..j]满足条件,即为max(arr[i..j])-min(arr[i..j]) <= num,那么arr[i..j]中的每一个子
* 数组,即为arr[k..l](i<=k<=l<=j)都满足条件,我们以子数组arr[i..j-1]为例说明,arr[i..j-1]的最大值只可能小
* 于或等于arr[i..j]的最大值,arr[i..j-1]的最小值只可能大于或等于arr[i..j]的最小值,所以于或等于arr[i..j-1]
* 必然可以满足条件。同理,arr[i..j]中的每一个子数组都满足条件。
* 2.如果子数组arr[i..j]不满足条件,那么所有包含arr[i..j]中的每一个子数组都不满足条件。即为arr[k..l](k<=i<=j<=k)
*
*代码设计:
*1.生成双端队列qmax和qmin。生成两个整形变量i和j,表示子数组的范围,即为arr[i..j]。生成整形变量res,表示所有满足条件的子数组的
*数量。
*2.令j不断向右移动(j++),表示arr[i..j]不断向右扩大,并不断更新qmax和qmin结构,保证qmax和qmin始终维持动态窗口的最大值和最小
*值的更新结构,一旦出现arr[i..j]不满足条件的情况,j向右扩的过程停止此时arr[i..j-1],arr[i..j-2],...arr[i..i+1],
*arr[i..i]一定都是满足条件的,所有以arr[i]作为第一个元素的子数组,满足条件数量为j-1个。于是令res += j-1.
*3.当进行完步骤2,令i向右移动一个位置,并对qmax和qmin做出相应的更新,然后重复步骤2即可。
* ,
*分析:
* 上述代码设计过程中,所有的下标值最多进qmax和qmin一次,出qmax和qmin一次,i和j的值也是不断增加,并且从来没有减少,所以整个
*代码的时间复杂度是O(N)。
*
* @author 雪瞳
*
*/
import java.util.LinkedList;
public class getNum {
public static int getNumArray(int arr[],int num) {
if(arr == null || arr.length == 0 || num < 0) {
return 0;
}
LinkedList<Integer> qmax = new LinkedList<>();
LinkedList<Integer> qmin = new LinkedList<>();
int i = 0;
int j = 0;
int res = 0;
//假设数组上一遍历状态为i..j,则i+1..j是都可以满足条件要求的,下一遍历状态可能达到i+1..k(k>j)
while(i<arr.length) {
while(j<arr.length) {
if(qmin.isEmpty() || qmin.peekLast() !=j) {
//自小变大
while(!qmin.isEmpty() && arr[qmin.peekLast()]>=arr[j]) {
qmin.pollLast();
}
qmin.addLast(j);
//自大变小
while(!qmax.isEmpty() && arr[qmax.peekLast()]<=arr[j]) {
qmax.pollLast();
}
qmax.addLast(j);
}
//跳出
if(arr[qmax.getFirst()]-arr[qmin.getFirst()] > num) {
break;
}
j++;
}
res += j-i;
//弹出队列首元素
if(qmin.peekFirst() == i) {
qmin.pollFirst();
}
if(qmax.peekFirst() == i) {
qmax.pollFirst();
}
i++;
}
return res;
}
原文地址:https://www.cnblogs.com/walxt/p/12468754.html
- Envoy架构概览(9):访问日志,MongoDB,DynamoDB,Redis
- 【前沿】TensorFlow Pytorch Keras代码实现深度学习大神Hinton NIPS2017 Capsule论文
- Linux 部署ASP.NET SQLite 应用 的坎坷之旅 附demo及源码
- 跨平台:使用OWIN 为WebAPI 宿主
- 如何在UWP中统一处理不同设备间的页面回退逻辑
- new and override
- 初识SignalR~仿QQ即时聊天(群发,单发)(Web,WPF等Demo演示)【上】
- 【翻译】A Next-Generation Smart Contract and Decentralized Application Platform
- asp.net回调javascript
- Oracle9i第2版中的UNT_FILE提高了文件输入/输出(I/O)功能。
- Python 工匠:善用变量来改善代码质量
- sql数据库打包部署安装
- 打包并自动安装sql数据库
- SQL 2008 r2 安装提示 visual studio 2008 版本错误解决方法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- (一)Mybatis的入门 - Titan的Mybatis系列学习笔记
- Hadoop安装与环境配置入门
- Elasticsearch源码解析:环境搭建
- SpringBoot整合JWT认证机制实现接口鉴权
- [Java] Java多线程的探索 -获取新闻标题
- Java中对文件进行MD5加密
- [数据结构] 使用最小堆思想实现哈夫曼编解码
- [数据结构] 括号符的匹配
- [数据结构] 平衡二叉查找树 (AVL树)
- 写给前端的算法进阶指南,我是如何两个月零基础刷200题
- [Java] 在Java中优雅地进行文件IO操作
- [Java] 日期与时间的一些操作
- 一起来用python实现一下十大经典排序算法
- [数据结构] 稀疏矩阵的存储
- [Python] 关于 asyncio 与 aiohttp 协程并发的探索