Оптимизация решения задачи на отрезки массива
Задача: Вводятся 2 числа n и k. Далее вводится массив длиной n. Задача - найти такой непрерывный отрезок массива длиной k, в котором наименьшее количество элементов больше предыдущего, и вывести этот минимум.
Пример: Ввод: 5 3
2 1 2 2 4
То есть нужно найти отрезок длиной 3. Смотрим: 2 1 2 - один такой элемент, который больше предыдущего (это вторая 2), далее 1 2 2 - тоже один такой элемент (первая 2), далее 2 2 4 - тоже 1 элемент (4).
Вывод: 1
Пример 2: Ввод:
7 4
1 2 3 3 3 1 2
Вывод: 0 (т.к. есть такой отрезок массива 3 3 3 1, в котором нет элементов, больших предыдущего)
Вот моё решение:
#include <iostream>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
int first = 0, second = k - 1, mn = 10e7;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
while (n > second) {
int count = 0;
for (int i = 0; i < k - 1; i++) {
if (arr[first + i + 1] > arr[first + i])
count += 1;
}
mn = min(mn, count);
if (mn == 0)
break;
second++;
first++;
}
cout << mn;
return 0;
}
Но, к сожалению, на тестирующую систему код не заходит из-за time limit. Может быть можно как-то оптимизировать решение? Возможно, искать минимум сразу при считывании? У меня не очень хорошее представление об этом. Помогите, пожалуйста!
Ответы (1 шт):
Ну у вас используется квадратичный алгоритм с количеством операций порядка n*k.
Но можно обойтись и линейным методом O(n)
Ведь на каждом шаге у вас из окна шириной k выходит одна разность, и входит одна разность. Значит, можно посчитать количество в первом промежутке длиной k, а потом на каждом шаге отнимать единицу, если выходящая разность учитывалась (просто проверить её ещё раз), и добавить единицу, если входящая разность учтётся как положительная. Таким образом, внутренность окна не пересчитывается.