18 最大值减去最小值小于或等于num的子数组数量
Table of Contents

ac

import java.util.LinkedList;
import java.util.Scanner;


public class Main {

    public static Scanner sc = new Scanner(System.in);

    /**
     * O(n)时间复杂度
     * @param args
     */
    public static void main(String[] args) {

        int n = sc.nextInt();
        int num = sc.nextInt();
        int[] arr = new int[n];
        for(int i=0;i<n;i++){
            int val = sc.nextInt();
            arr[i] = val;
        }
        // 存最小,最大的双端队列, 存储的是下标
        LinkedList<Integer> queMin = new LinkedList();
        LinkedList<Integer> queMax = new LinkedList();

        int res = 0;
        int i = 0;
        int j = 0;
        while (i < n){
            // i, j 范围内,最小最大值需要不断的更新并判断
            while (j < n){
                while (!queMin.isEmpty() && arr[queMin.peekLast()] >= arr[j]){
                    queMin.pollLast();
                }
                queMin.addLast(j);
                while (!queMax.isEmpty() && arr[queMax.peekLast()] <= arr[j]){
                    queMax.pollLast();
                }
                queMax.addLast(j);
                if(arr[queMax.getFirst()] - arr[queMin.getFirst()] > num){
                    break;
                }
                // j 往后移动
                j++;
            }
            // j移不动了,就开始统计,开始 i++
            // arr[i,j], arr[i, j-1], arr[i, j-2] ... 等
            if(!queMin.isEmpty() && queMin.peekFirst() == i){
                queMin.pollFirst();
            }
            if(!queMax.isEmpty() && queMax.peekFirst() == i){
                queMax.pollFirst();
            }
            res += j - i;
            i ++;
        }
        System.out.println(res);
    }

}