暴力编码过于复杂,建议看代码注释 暴力解题方式,梅什么 好说的。 先排序,方便计算。因为要时间最少,肯定是取数量连续的水桶。所以排序好。 然后通过多重循环取要均等的Pi个水桶,重A0开始遍历所有的连续值场景生成这些场景的水桶数组,并计算均等她它们需要的时间,循环结束后如果时间变小了,存入返回数组中。
public int[] solve (int n, int q, int[] a, int[] p) {
//水桶从小到大排序先,方便取连续大小的水桶。
Arrays.sort(a);
//水桶均等所需时间的数组。
int[] resArr = new int[p.length];
// 最外层操作数组遍历,不解释
for (int i = 0; i < p.length; i++) {
int num = p[i];
// 小于等于1的场景无需处理,记录0即可。
if (num <= 1) {
resArr[i] = 0;
continue;
}
//定义最终需要加水的水桶下标起始点(changeIndexStart,缩写了)
int cis = 0;
//每次操作先假设出最少时间(取到最大范围,后面比较后替换)
int minTime = 1 << 30;
// 遍历出所有需要加水的水桶数组场景(例如1234取2的时候场景为:12,23,34)
for (int j = 0; j < a.length - num + 1; j++) {
int[] compareArr = new int[num];
for (int k = 0; k < num; k++) {
compareArr[k] = a[j + k];
}
//计算出当前加水的水桶数组所需时间
int timeCost = getTimeCost(compareArr);
//如果时间更少则更新此次操作的时间和下标起始
if (timeCost < minTime) {
minTime = timeCost;
cis = j;
}
}
//循环结束后此次加水的下标和时间就最终确认了,这是记录返回值,并更新水桶中的水量(只需要和最后一桶一样多即可,因为排过序了)
resArr[i] = minTime;
for (int c = 0; c < num - 1; c++) {
a[cis + c] = a[cis + num - 1];
}
}
return resArr;
}
private int getTimeCost(int[] compareArr){
int count = 0;
// 倒序进行比较进行加水,每次比较加到相等为止。因为排序过了,所以直接大小比较并在加水时计数即可。
for (int i = compareArr.length - 1; i > 0; i--) {
while (compareArr[i] > compareArr[i - 1]) {
count++;
compareArr[i - 1] = compareArr[i - 1] + 1;
}
}
return count;
}
}