Вопрос: Напишите функцию, которая возвращает количество переходов, необходимых для достижения конца целочисленного массива, представляющего количество возможных шагов.

Например, учитывая [2, 3, 1, 0, 4, 1, 5, 1, 0, 2], вы должны вернуть 4,
Например, учитывая [2, 1, 3, 2, 1, 0, 2], вы должны вернуть nil.
Подсказки:
- Вам нужно перебрать массив и для каждого элемента вычислить максимальное достигнутое значение,
- Если ваш текущий элемент больше, чем достигнутый максимум, вы не можете достичь конца.
Решение:
func numberOfJumps(array: [Int]) -> Int? {
// 1.
guard array.count > 1 else { return 0 }
// 2.
var maxReached = array[0]
var steps = array[0]
var jump = 1
// 3.
for i in 1..<array.count {
if i == array.count - 1 {
// 4.
return jump
}
// 5.
maxReached = max(maxReached, i + array[i])
// 6.
steps -= 1
if steps == 0 {
// 7.
jump += 1
if i >= maxReached {
// 8.
return nil
}
// 9.
steps = maxReached - i
}
}
// 10.
return nil
}
Пояснения:
1. Если в массиве меньше двух элементов, то переходы в конец не нужны.
guard array.count > 1 else { return 0 }
2. Определим несколько переменных (максимально достигнутый индекс, количество возможных шагов, количество выполненных прыжков).
var maxReached = array[0] var steps = array[0] var jump = 1
3. Теперь давайте повторим массив.
for i in 1..<array.count {
4. Если мы достигли последнего элемента массива, вернуть количество сделанных прыжков.
if i == array.count - 1 {
return jump
}
5. Обновим индекс максимального охвата (максимум между предыдущим максимальным и текущим индексом плюс возможное количество шагов).
maxReached = max(maxReached, i + array[i])
6. Давайте сделаем один шаг и уменьшим количество возможных шагов.
steps -= 1
7. Если количество шагов равно 0, увеличим количество прыжков.
if steps == 0 {
jump += 1
8. Если текущий индекс равен или больше максимально достигнутого, мы не можем достичь конца, возвращаем nil.
if i >= maxReached {
return nil
}
9. Обновите количество шагов по разнице между максимальным достигнутым и текущим индексом.
steps = maxReached — i
10. На данный момент мы не достигли и не можем достичь конца массива, возвращаем nil.
return nil
Сложность:
- Временная сложность: как максимум, мы перебираем все элементы массива, временная сложность является линейной O (n),
- Сложность пространства: поскольку нам нужно несколько целочисленных переменных (индексы и счетчик), сложность пространства постоянна O (1).
Тест-кейсы:
public func testNumberOfJumps() {
assert(numberOfJumps(array: [2, 3, 1, 0, 4, 1, 5, 1, 0, 2]) == 4, "numberOfJumps 1 not equal")
assert(numberOfJumps(array: [2, 1, 3, 2, 1, 0, 2]) == nil, "numberOfJumps 2 not equal")
}
Следовать за:
Нет дополнительного вопроса.
‹‹ Структуры данных, алгоритмы и вопросы для интервью ››