最大值减去最小值小于或等于 num 的子数组数量问题
最大值减去最小值小于或等于 num 的子数组数量问题
作者:Grey
原文地址:
博客园:最大值减去最小值小于或等于 num 的子数组数量问题
CSDN:最大值减去最小值小于或等于 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[L..R]
达标,则 arr 中内部的任何一个子数组都达标;
第二个结论:arr[L..R]
不达标,则 arr 扩充后肯定也不达标;
第三个结论:L...R
范围如果达标,其子数组个数为:R - L
。
利用滑动窗口算法,我们可以得到必须以l位置作为左边界的情况下,有多少达标的数组。
完整代码如下(含对数器)
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static int getNum(int[] arr, int num) {
LinkedList<Integer> qMax = new LinkedList<>();
LinkedList<Integer> qMin = new LinkedList<>();
int ans = 0;
int l = 0;
int r = 0;
while (l < arr.length) {
while (r < arr.length) {
while (!qMax.isEmpty() && arr[qMax.peekLast()] <= arr[r]) {
qMax.pollLast();
}
qMax.addLast(r);
while (!qMin.isEmpty() && arr[qMin.peekLast()] >= arr[r]) {
qMin.pollLast();
}
qMin.addLast(r);
if (arr[qMax.peekFirst()] - arr[qMin.peekFirst()] > num) {
break;
}
r++;
}
// r是以l作为左边界,第一个不满足条件的位置
ans += (r - l);
// 弹出过期位置
if (!qMax.isEmpty() && qMax.peekFirst() == l) {
qMax.pollFirst();
}
// 弹出过期位置
if (!qMin.isEmpty() && qMin.peekFirst() == l) {
qMin.pollFirst();
}
l++;
}
return ans;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
System.out.println(getNum(arr,m));
in.close();
}
}
更多#
作者:GreyZeng
出处:https://www.cnblogs.com/greyzeng/p/16966417.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
你可以在这里自定义其他内容
本文来自博客园,作者:Grey Zeng,转载请注明原文链接:https://www.cnblogs.com/greyzeng/p/16966417.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程