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

Например, учитывая [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")
}

Следовать за:

Нет дополнительного вопроса.

‹‹ Структуры данных, алгоритмы и вопросы для интервью ››