Вопрос: Напишите функцию, которая возвращает степень X ^ Y (не используйте встроенные функции).

Например, учитывая 2 ^ 10, вернуть 1024,
Например, учитывая 10 ^ 2, вернуть 100.
Подсказки:
- Вы можете сделать это через рекурсивную функцию,
- Каковы базовые случаи?,
- Что делать, если мощность нечетное число.
Решение:
func power(radix: Int, power: Int) -> Int {
// 1.
var memo = [Int: Int]()
return powerMemo(radix: radix, power: power, memo: &memo)
}
// 2.
func powerMemo(radix: Int, power: Int, memo: inout [Int: Int]) -> Int {
// 3.
guard radix != 0 else { return 0 }
guard power >= 0 else { return 0 }
guard power != 0 else { return 1 }
guard power != 1 else { return radix }
if let value = memo[power] {
// 4.
return value
} else {
// 5.
let value = powerMemo(radix: radix, power: power / 2, memo: &memo)
* powerMemo(radix: radix, power: power / 2, memo: &memo)
* (power % 2 == 0 ? 1 : radix)
// 6.
memo[power] = value
return value
}
}
Пояснения:
1. Давайте создадим частичный результат для мемоизации и передадим его помощнику функции.
var memo = [Int: Int]() return powerMemo(radix: radix, power: power, memo: &memo)
2. Это вспомогательная функция, которая является рекурсивной и создает частичные результаты, пока мы не найдем целевой результат.
func powerMemo(radix: Int, power: Int, memo: inout [Int: Int]) -> Int {
3. Это базовые случаи для мощности, основание == 0, мощность ‹= 1 (здесь мы не рассматриваем отрицательную мощность).
guard radix != 0 else { return 0 }
guard power >= 0 else { return 0 }
guard power != 0 else { return 1 }
guard power != 1 else { return radix }
4. Если значения уже рассчитаны, возвращаем сохраненный результат.
if let value = memo[power] {
return value
5. Поскольку X²N == X^N * X^N, мы можем рекурсивно и уменьшить число мощности (разделить на два и позаботиться о числах степени шансов) до достижения одного из базовых случаев.
let value = powerMemo(radix: radix, power: power / 2, memo: &memo)
* powerMemo(radix: radix, power: power / 2, memo: &memo)
* (power % 2 == 0 ? 1 : radix)
6. Сохраним текущий результат и вернем его.
memo[power] = value
return value
}
}
Сложность:
- Временная сложность: поскольку мы каждый раз уменьшаем задачу на два, как при бинарном поиске, временная сложность равна O(log y), где y - мощность,
- Пространственная сложность: стек вызовов и словарь частичных результатов составляют временную сложность O(y).
Тест-кейсы:
public func testPower() {
assert(power(radix: 2, power: 10) == 1024, "power 1 not equal")
assert(power(radix: 10, power: 2) == 100, "power 2 not equal")
}
Следовать за:
Сделайте это итеративным или используйте табуляцию (или сделайте и то, и другое!).
‹‹ Структуры данных, алгоритмы и вопросы для интервью ››