Дается непустой нуль-индексированный массив A, состоящий из N целых чисел. Пара целых чисел (P, Q), такая, что 0 ≤ P < Q < N, называется срезом массива A (обратите внимание, что срез содержит как минимум два элемента). Среднее значение среза (P, Q) представляет собой сумму A [P] + A [P + 1] +... + A [Q], деленную на длину среза. Если быть точным, среднее равно (A [P] + A [P + 1] +... + A [Q])/(Q - P + 1).
Например, массив A такой, что:
A[0] = 4
A[1] = 2
A[2] = 2
A[3] = 5
A[4] = 1
A[5] = 5
A[6] = 8
содержит следующие фрагменты примера:
- срез (1, 2), среднее значение которого (2 + 2)/2 = 2;
- срез (3, 4), среднее значение которого (5 + 1)/2 = 3;
- срез (1, 4), среднее значение которого (2 + 2 + 5 + 1)/4 = 2,5.
Цель состоит в том, чтобы найти начальную позицию среза, среднее значение которого минимально.
Напишите функцию:
class Solution { public int solution(int[] A); }
что, учитывая непустой нуль-индексированный массив A, состоящий из N целых чисел, возвращает начальную позицию среза с минимальным средним значением. Если имеется более одного среза с минимальным средним значением, вы должны вернуть наименьшую начальную позицию такого фрагмента.
Например, данный массив A такой, что:
A[0] = 4
A[1] = 2
A[2] = 2
A[3] = 5
A[4] = 1
A[5] = 5
A[6] = 8
функция должна возвращать 1, как объяснялось выше.
Предположим, что:
- N - целое число в диапазоне [2..100.000];
- каждый элемент массива A является целым числом в диапазоне [-10,000..10,000].
Сложность:
- ожидаемая наихудшая временная сложность - O (N);
- ожидаемая наихудшая сложность пространства - это O (N), за пределами входного хранилища (не считая хранения, необходимого для входных аргументов).
Элементы входных массивов могут быть изменены.
Это мое лучшее решение, но, очевидно, не оптимальное с точки зрения сложности времени.
Любые идеи?
public int solution(int[] A) {
int result = 0;
int N = A.length;
int [] prefix = new int [N+1];
for (int i = 1; i < prefix.length; i++) {
prefix[i] = prefix[i-1] + A[i-1];
}
double avg = Double.MAX_VALUE;
for (int i = 1; i < N; i++) {
for (int j = i+1; j <=N; j++) {
double temp = (double)(prefix[j]-prefix[i-1]) /(double)(j-i+1);
if (temp < avg) {
avg = temp;
result = i-1;
}
}
}
return result;
}