Я знаю, что простой способ использовать транспонирование для поворота квадратной матрицы на 90 градусов, но я пишу решение, как будто я этого не знаю (другими словами, я хочу сделать замену). Общая идея ниже состоит в том, чтобы поменять слой за слоем. offset
представляет, какой слой (вовнутрь внутрь) заменяется.
Здесь алгоритм (обратите внимание, что он завернут в class
потому что это вещь Leetcode):
class Solution:
def rotate(self, matrix):
for start in range(len(matrix)//2):
end = len(matrix) - start - 1
# swap all 4 coordinates:
for offset in range(start, end):
# swap top_left over top_right
temp, matrix[start+offset][end] = matrix[start+offset][end], matrix[start][start+offset]
# swap top_right -> bottom_right
temp, matrix[end][end-offset] = matrix[end][end-offset], temp
# swap bottom_right -> bottom_left
temp, matrix[end-offset][start] = matrix[end-offset][start], temp
# swap bottom_left -> top_left
matrix[start][start+offset] = temp
Это работает для некоторых ручных тестов с малыми матрицами, а также с меньшими входными тестовыми примерами в представлении Leetcode. Однако он не работает на следующем входе:
[[ 2, 29, 20, 26, 16, 28],
[12, 27, 9, 25, 13, 21],
[32, 33, 32, 2, 28, 14],
[13, 14, 32, 27, 22, 26],
[33, 1, 20, 7, 21, 7],
[ 4, 24, 1, 6, 32, 34]]
Ожидаемый результат:
[[ 4, 33, 13, 32, 12, 2],
[24, 1, 14, 33, 27, 29],
[ 1, 20, 32, 32, 9, 20],
[ 6, 7, 27, 2, 25, 26],
[32, 21, 22, 28, 13, 16],
[34, 7, 26, 14, 21, 28]]
Мой выход:
[[ 4, 33, 13, 32, 12, 2],
[24, 1, 7, 33, 27, 29],
[ 1, 20, 32, 2, 14, 20],
[ 6, 28, 32, 27, 25, 26],
[32, 21, 22, 9, 13, 16],
[34, 7, 26, 14, 21, 28]]
Эта матрица достаточно велика, чтобы ей стало скучно проходить через алгоритм вручную, как я делал для небольших случаев ввода для отладки. Где ошибка в моей реализации?
Ваше offset
выключено, попробуйте
for offset in range(0, end-start):
Ваши (случайные) тестовые данные трудно отслеживать и отлаживать. Лучше использовать читаемый набор.
Также кажется, что реализация делает чрезмерные свопы.
Достаточно вспомнить значение ячейки, сдвинуть ячейки данных циклически, получить запоминаемое значение.
Вот простая реализация вращения с матом, заполненным последовательными номерами:
n = 5
nm = n - 1
mat = []
for i in range(n):
a = [x for x in range(n*i, n*i+n)]
mat.append(a)
for i in range(n):
(print(mat[i]))
for row in range((n + 1)//2):
for col in range(n//2):
t = mat[row] [col]
mat[row][col] = mat[nm-col][row]
mat[nm-col][row] = mat[nm-row][nm-col]
mat[nm-row][nm - col] = mat[col][nm-row]
mat[col][nm-row] = t
print("")
for i in range(n):
(print(mat[i]))
[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
[20, 15, 10, 5, 0]
[21, 16, 11, 6, 1]
[22, 17, 12, 7, 2]
[23, 18, 13, 8, 3]
[24, 19, 14, 9, 4]
test = [[ 2, 29, 20, 26, 16, 28],
[12, 27, 9, 25, 13, 21],
[32, 33, 32, 2, 28, 14],
[13, 14, 32, 27, 22, 26],
[33, 1, 20, 7, 21, 7],
[ 4, 24, 1, 6, 32, 34]]
expected = [[ 4, 33, 13, 32, 12, 2],
[24, 1, 14, 33, 27, 29],
[ 1, 20, 32, 32, 9, 20],
[ 6, 7, 27, 2, 25, 26],
[32, 21, 22, 28, 13, 16],
[34, 7, 26, 14, 21, 28]]
# rotate one direction
for row in zip(*reversed(test)):
print(row)
# rotate the other
for row in zip(*test):
print(row)
# if it is important to have the matrix as a list of lists
answer = list(map(list,list(zip(*reversed(test)))))
print(answer == expected)
Чтобы сделать это вращение, значение i-й строки и j-го столбца входной матрицы должно быть равно j-й строке i-го столбца столбцов выходных матриц (транспонирование) и (следующего шага) следует обратить вспять. Если бы я был вами, я бы определил пустую матрицу и (скажем, TRANSPOSE, имеет тот же размер, что и входная матрица), определит 2 для циклов (i в диапазоне len (matrix) и j в диапазоне len (matrix). я бы написал
TRANSPOSE[i][j] = matrix[j][i]
Теперь у меня есть матрица, которую вы хотите с перевернутыми столбцами. Теперь нам нужно отменить столбцы, чтобы получить то, что вы хотите, поэтому я бы определил другую для циклов с теми же переменными и диапазоном, и вам понадобится еще одна пустая матрица с таким же размером, или мы снова сможем использовать матрицу ввода, позвольте использовать матрицу ввода в этом случае.
matrix[i][j] = TRANSPOSE[i][len(matrix) - j - 1]
и возвратная matrix