Этот пост предназначен для решения проблемы кодильности — циклического вращения.
Я бы посоветовал вам внимательно прочитать описание проблемы на веб-сайте Codility, сначала попробовать собственное решение, и если вы действительно застряли, даже потратив значительное время на решение проблемы, найдите решение, представленное ниже.
Я постараюсь предоставить подробное описание того, почему я решил написать решение определенным образом, но обратите внимание, что я не считаю себя «гуру» Python и, следовательно, призываю вас попытаться сделать решение еще лучше и дайте мне знать ваше мнение. мысли в разделе комментариев, а также :)
def solution(A, K): if K == len(A) or len(A) == 0 or len(A) == 1: return A elif K > len(A): K = K % len(A) else: pass B = A[len(A)-K:] C = A[:len(A)-K] return B + C
Подробнее о решении:
if K == len(A) or len(A) == 0 or len(A) == 1
Приведенный выше «оператор if» пытается отловить следующие простые случаи в начале решения, чтобы нам не приходилось тратить время и память на обработку этих случаев:
- Если мы будем вращать массив столько раз, сколько его длины, мы всегда будем получать один и тот же массив. Пример — [1, 2, 3], повернутый 3 раза, даст нам [3, 1, 2] → [2, 3, 1] → [1, 2, 3].
- Если массив пуст, в результате мы всегда будем получать пустой массив.
- Если в массиве только 1 элемент, мы всегда будем получать один и тот же массив, независимо от того, будем ли мы вращать его 10 раз или 100 000 раз.
elif K > len(A): K = K % len(A) else: pass
Поскольку мы знаем, что если мы вращаем массив столько раз, сколько длина массива, мы всегда будем получать один и тот же массив, поэтому в случае очень высокого значения для «K» мы могли бы безопасно игнорировать значение K, которое равно кратно длине массива. Например, если длина массива равна 80, а значение «K» равно 82, вместо того, чтобы пытаться повернуть массив 82 раза, мы можем повернуть его всего на 82 % 80 = 2 раза и получить тот же результат. Символ % в Python называется оператором Modulo. Он возвращает остаток от деления левого операнда на правый операнд.
Программа перейдет в состояние else, когда K уже меньше len(A), и в этом случае нам не нужно ничего делать, поэтому мы просто используем pass.
B = A[len(A)-K:] C = A[:len(A)-K] return B + C
Последняя часть - это просто нарезка, приходящая на помощь, где мы можем создать 2 массива, первый «B», который дает нам массив A, который начинается с индекса len(A)-K, поэтому для массива A = [1,2,3 ,4,5] и K =2, массив B будет начинаться с индекса 5 -2 = 3, т.е. [4, 5]. Точно так же для того же примера массива C с нарезкой даст нам элементы массива до индекса 3, т.е. C будет [1, 2, 3]. С указанными выше двумя наборами массивов мы можем с радостью вернуть массив B + массив C в качестве результата, который даст нам [4, 5, 1, 2, 3], который представляет собой массив A, повернутый 2 раза.
Обратите внимание, что мы могли бы вообще не присваивать массивы B и C и написать логику нарезки непосредственно в операторе return, как показано ниже.
return A[len(A)-K::]+ A[:len(A)-K]