Не уверен в вашем вопросе, но я думаю, что у меня есть решение O (N):
int M(const vector<int> &nums)
{
int n_jumps = 0;
int cur_pos = 0;
int prev_pos = 0;
int next_jump = 0;
int max_value = 0;
int value;
int i;
while (cur_pos + nums[cur_pos] < nums.size() - 1)
{
next_jump = 0;
max_value = 0;
i = cur_pos > 0 ? prev_pos + nums[prev_pos] + 1 : 1;
for (; i <= cur_pos + nums[cur_pos]; ++i)
{
value = i + nums[i];
if (value >= nums.size() - 1) return n_jumps + 2;
if (max_value < value)
{
max_value = value;
next_jump = i - cur_pos;
}
}
prev_pos = cur_pos;
cur_pos += next_jump;
++n_jumps;
}
return n_jumps + 1;
}
Каждый раз, когда мы выбираем, сколько прыгать, максимизируя расстояние, которое мы можем преодолеть в этом и следующий ход Последний переход может быть только максимально допустимым переходом, то есть значением элемента, на котором мы находимся.
Обратите внимание, что при переходе к следующему элементу нам не нужно проверять доступные элементы с предыдущей позиции (что дает нам O (N)).
Можно доказать, что этот алгоритм находит минимальное количество прыжков, используя математическую индукцию.