Оптимизация решения задачи на отрезки массива

Задача: Вводятся 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 шт):

Автор решения: MBo

Ну у вас используется квадратичный алгоритм с количеством операций порядка n*k.

Но можно обойтись и линейным методом O(n)

Ведь на каждом шаге у вас из окна шириной k выходит одна разность, и входит одна разность. Значит, можно посчитать количество в первом промежутке длиной k, а потом на каждом шаге отнимать единицу, если выходящая разность учитывалась (просто проверить её ещё раз), и добавить единицу, если входящая разность учтётся как положительная. Таким образом, внутренность окна не пересчитывается.

→ Ссылка