Не могу обнаружить ошибку в моем коде матрицы поворота

1

Я знаю, что простой способ использовать транспонирование для поворота квадратной матрицы на 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]]

Эта матрица достаточно велика, чтобы ей стало скучно проходить через алгоритм вручную, как я делал для небольших случаев ввода для отладки. Где ошибка в моей реализации?

Теги:
algorithm
matrix

4 ответа

4
Лучший ответ

Ваше offset выключено, попробуйте

for offset in range(0, end-start):
1

Ваши (случайные) тестовые данные трудно отслеживать и отлаживать. Лучше использовать читаемый набор.

Также кажется, что реализация делает чрезмерные свопы.

Достаточно вспомнить значение ячейки, сдвинуть ячейки данных циклически, получить запоминаемое значение.

Вот простая реализация вращения с матом, заполненным последовательными номерами:

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]
0
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)
0

Чтобы сделать это вращение, значение 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню