算法总结之 最大值减去最小值或等于num的子数组数量

给定数组arr和整数num,共返回有多少个子数组满足  <= num

数组长度N    时间复杂度O(N)

package TT;

import java.util.LinkedList;

public class Test127 {

	  public int getNum(int[] arr, int num){
		  if(arr==null || arr.length == 0){
			  return 0;
		  }
		  LinkedList<Integer> qmin = new LinkedList<Integer>();
		  LinkedList<Integer> qmax = new LinkedList<Integer>();
		  int i = 0;
		  int j = 0;
		  int res = 0;
		  while(i<arr.length){
			  while(j<arr.length){
			  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++;
		  }
		  if(qmin.peekFirst()==i){
			  qmin.pollFirst();
		  }
		  if(qmax.peekFirst()==i){
			  qmax.pollFirst();
		  }

		  res += j-i;
		  i++;
		  }
		  return res;
	  }

}

  

时间: 2024-08-29 12:11:46

算法总结之 最大值减去最小值或等于num的子数组数量的相关文章

最大值减去最小值小于或等于num的子数组数量

[说明]: 本文是左程云老师所著的<程序员面试代码指南>第一章中“最大值减去最小值小于或等于num的子数组数量”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书. 感谢左程云老师的支持. [题目]: 给定数组 arr 和整数 num,共返回多少个字数组满足如下情况: max(arr[i...j]) - min(arr[i...j]) <= num max(arr[i...j]) 表示字数组 arr[i...j] 中的最大

左神算法书籍《程序员代码面试指南》——1_10最大值减去最小值小于或等于num的子数组数量

[题目]给定数组arr和整数num,共返回有多少个子数组满足如下情况:max(arr[i.j]) - min(arr[i.j]) <= num max(arfi.j])表示子数组ar[ij]中的最大值,min(arli.j])表示子数组arr[i.j]中的最小值.[要求]如果数组长度为N,请实现时间复杂度为O(N)的解法.[题解]使用两个单调栈,一个栈维持从大到小的排序,头部永远是最大值一个维持从小到大的排序,头部永远都是最小值然后使用窗口进行数据移动当右移后,最大最小差超过num时,计算这段数

【队列】最大值减去最小值小于等于num的子数组数量

摘自<程序员代码面试指南> 题目: 给定数组 arr 和整数 num, 共返回有多少个?数组满?如下情况:max(arr[i...j]) - min(arr[i...j]) <= nummax(arr[i...j])表示?数组 arr[i...j]中的最?值,min(arr[i...j])表示?数组arr[i...j]中的最小值. 题解: 区间最大最小值,立刻联想到单调栈(双端队列),不过稍微麻烦一些,需要在此基础上总结一些规律. 如果?数组 arr[i..j]满?条件, 即 max(a

1.10 最大值减去最小值小于或等于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]中的最小值 [要求]: 如果数组长度为N,请实现时间复杂度为O(N)的解法 原文地址:https://www.cnblogs.com/latup/p/9908350.html

栈和队列----最大值减去最小值小于等于num的子数组的数量

最大值减去最小值小于等于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] 中的最小值.如果数组的长度为N,要求时间复杂度是 O(N). [解析] 使用双端队列,qmax维护着窗口子数组arr[i..j]的最大值更新的结构,qmin维护着窗口子数组arr[i.

[程序员代码面试指南]栈和队列-最大值减去最小值 小于或等于num 的子数组的数量(双端队列)

题目 给定数组arr和整数num,求数组的子数组中有多少个的满足"最大值减去最小值<=num". 解题思路 分析题目,有结论: 如果数组arr[i...j]满足条件,则它的每一个子数组都满足条件. 如果数组arr[i...j]不满足条件,则包含它的每一个数组都不满足条件. 数据结构:用i.j表示当前窗口,分别使用两个双端队列维护窗口的最大值和最小值. 具体地,每次更新两个双端队列,检查当前的窗口是否满足条件,满足则j++,不满足则cnt+=j-i,更新双端队列,i++,j不变.若

求数组所有区间最大值减去最小值之差的和(贝壳笔试题)

这个题直接暴力求解的话时间复杂度肯定是不行的,所以,我们要计算每个数值的贡献,对每一个数求他当最小值当了多少次,当最大值当了多少次,最后当最大值的次数乘以这个数值减去当最小值的次数乘以数值就得到这个数的贡献,依次把这n个数的贡献加起来就是整个极差之和. 在计算一个数当了多少最值的时候,我们要理解问题,因为区间是连续的,所以,以最小值为例,如果一个数是当前这段区间的最小值,那么他一定是当前这段区间最小的(这不废话),所以,我们就找到他往左做多能找到多少个连续的数都比他大,记录这个位置,同理找他右边

POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

[编程之美] 2.14 求数组的子数组之和的最大值

问题描述:给定一个包含N个整数的数组,求数组的子数组之和的最大值. 这是递归和贪心策略的一个经典问题.现在,对这个问题进行一下总结. 1 明确题意 题目中的子数组要求是连续的,也就是数组中的某个连续部分. 如果数组中都是正整数,直接相加就行.因此,主要是要考虑负数的情况. 2 直接求所有的子数组和 最简单且容易理解的解法是求出所有的子数组和,然后保存最大的和. int MaxSum(int *A, int n) { int maximum = -INF; int sum = 0; int i =