程序员代码面试指南第二版 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 和 num,其中 n 表示数组 arr 的长度
第二行输入n个整数,表示数组arr中的每个元素
输出描述:
输出给定数组中满足条件的子数组个数
示例1
输入
5 2
1 2 3 4 5
输出
12
第一次做; 核心: 寻找子数组的方式, 两个约束条件, 维护最大值最小值索引队列; 所有元素索引都会进队一次, 出队一次; 在内循环外面更新res
import java.util.Scanner;
import java.util.LinkedList;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String curr = sc.nextLine();
int n = Integer.parseInt(curr.split(" ")[0]);
int num = Integer.parseInt(curr.split(" ")[1]);
String[] str = sc.nextLine().split(" ");
int[] arr = new int[n];
for(int i=0; i<arr.length; i++)
arr[i] = Integer.parseInt(str[i]);
int res = 0;
LinkedList<Integer> qmin = new LinkedList<>();
LinkedList<Integer> qmax = new LinkedList<>();
int left=0, right=0, max, min;
while(left < n){
while(right < n){
if(qmin.isEmpty()){
qmin.add(right);
qmax.add(right);
right++;
}
else{
while(!qmax.isEmpty() && arr[right] > arr[qmax.peekLast()]){
qmax.pollLast();
}
if(qmax.isEmpty() || qmax.peekLast()!=right)
qmax.add(right);
while(!qmin.isEmpty() && arr[right] < arr[qmin.peekLast()]){
qmin.pollLast();
}
if(qmin.isEmpty() || qmin.peekLast() != right)
qmin.add(right);
if(qmax.peek()<left)
qmax.poll();
if(qmin.peek()<left)
qmin.poll();
max = arr[qmax.peek()];
min = arr[qmin.peek()];
if(max - min > num)
break;
right++;
}
}
res += right - left;
left++;
}
System.out.println(res);
}
}
左神的高效简洁代码; 和我的逻辑是一样的, 但是进行了综合
import java.util.Scanner;
import java.util.LinkedList;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String curr = sc.nextLine();
int n = Integer.parseInt(curr.split(" ")[0]);
int num = Integer.parseInt(curr.split(" ")[1]);
String[] str = sc.nextLine().split(" ");
int[] arr = new int[n];
for(int i=0; i<arr.length; i++)
arr[i] = Integer.parseInt(str[i]);
int res = 0;
LinkedList<Integer> qmin = new LinkedList<>();
LinkedList<Integer> qmax = new LinkedList<>();
int i=0, j=0, max, min;
while(i<n){
while(j<n){
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++;
}
System.out.println(res);
}
}