查找接口成功率最优时间段
题目描述
服务之间交换的接口成功率作为服务调用关键质量特性,某个时间段内的接口失败率使用一个数组表示,数组中每个元素都是单位时间内失败率数值,数组中的数值为0~100的整数,给定一个数值(minAverageLost)表示某个时间段内平均失败率容忍值,即平均失败率小于等于minAverageLost,找出数组中最长时间段,如果未找到则直接返回NULL。
输入描述
输入有两行内容,第一行为{minAverageLost},第二行为{数组},数组元素通过空格(” “)分隔,minAverageLost及数组中元素取值范围为0~100的整数,数组元素的个数不会超过100个。
输出描述
找出平均值小于等于minAverageLost的最长时间段,输出数组下标对,格式{beginIndex}-{endIndx}(下标从0开始),
如果同时存在多个最长时间段,则输出多个下标对且下标对之间使用空格(” “)拼接,多个下标对按下标从小到大排序。
用例
输入 | 1 0 1 2 3 4 |
输出 | 0-2 |
说明 | 输入解释:minAverageLost=1,数组[0, 1, 2, 3, 4] 前3个元素的平均值为1,因此数组第一个至第三个数组下标,即0-2 |
输入 | 2 0 0 100 2 2 99 0 2 |
输出 | 0-1 3-4 6-7 |
说明 | 输入解释:minAverageLost=2,数组[0, 0, 100, 2, 2, 99, 0, 2] 通过计算小于等于2的最长时间段为: 数组下标为0-1即[0, 0],数组下标为3-4即[2, 2],数组下标为6-7即[0, 2],这三个部分都满足平均值小于等于2的要求, 因此输出0-1 3-4 6-7 |
解析
这个题逻辑层面来看 比较简单。但是编程时发现还是蛮痛苦的。
- 最小值和输入数组的初始化
- 找出这个数组中 满足连续的 几个数的平均数小于 等于最小值的 下标范围
例如:
输入
3
1 2 3 5 8 1 1 1
首先肯定 能找到的 0-3 因为 1+2+3+ 5=11 再除以4 其值小于3 的
然后就是 后面的 三个1 即 5-7
因此可以输出结果 0-3 5-7 但是真实结果真是这样的吗? 这个8就一定会被舍弃掉吗?其实这个答案是有问题的。如果你把所有内容全部求平均 其结果为 22/8 是小于3的 所以这个结果应该为0-7 而并非 0-3 5-7- 可以考虑使用递归的方式来做,不断的移动数组的游标,尽可能找出以该游标开始的最大的范围的结束索引。下次递归时,就在该区间范围外进行递归即可。
示例代码
import java.util.Scanner;
public class Test1 {
public static boolean flag = false;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int minAvg = Integer.parseInt(sc.nextLine());
String input = sc.nextLine();
String inputArr[] = input.split(" ");
int arr[] = new int[inputArr.length];
for (int i = 0; i < inputArr.length; i++) {
arr[i] = Integer.parseInt(inputArr[i]);
}
dfs(0, arr, minAvg);
if (!flag) {
System.out.println("NULL");
}
}
// 计算 某个索引 开始 一直到数组最后的 最大可能值 1
public static void dfs(int left, int arr[], int minAvg) {
if (left == arr.length)
return;
int count = 0;
double sum = 0.0;
int tempLeft = left;
int objRight = left;// 目标最值右
for (; tempLeft < arr.length; tempLeft++) {
sum += arr[tempLeft];
count++;
if (sum / count <= minAvg) {
objRight = tempLeft;
}
}
if (objRight > left) {
flag = true;
System.out.print(left + "-" + objRight + " ");
left = objRight; // 找到一个 区间满足 那下次从这个区间的下一个开始往下找 不然 找出的 可能为该区间的子区间
}
dfs(left + 1, arr, minAvg);
}
}
代码运行结果