简体   繁体   中英

Rotate a matrix by 90 degrees

Background

I am solving a standard LeetCode Question 48 . I know there are many solutions out there but I am trying to solve the question with an approach that makes sense to me. I am basically trying to rotate a matrix 90 degrees. I am trying to swap each value of each layer of the square matrix.

Here is my code:

def rotate_image(matrix):
    top = 0
    bottom = len(matrix)
    left = 0
    right = len(matrix[0])
    total_layers = round(bottom / 2)

    for i in range(0, total_layers):

        for j in range(left, right - 1):
            top_left = matrix[top][j]
            top_right = matrix[j][right - 1]
            bottom_right = matrix[bottom - 1][right - (j + 1)]
            bottom_left = matrix[bottom - (1+j)][left]
            matrix[top][j] = bottom_left
            matrix[j][right - 1] = top_left
            matrix[bottom - 1][right - (j + 1)] = top_right
            matrix[bottom - (1 + j)][left] = bottom_right
        top += 1
        left += 1
        right -= 1
        bottom -= 1
    print(matrix)

For some reason, my code is passing most cases but when I try the following case

print(rotate_image([[5, 1, 9, 11], [2, 4, 8, 10], [13, 3, 6, 7], [15, 14, 12, 16]]))

it fails. I have spent 2 hours trying to debug it and I may be over looking something but not sure what it is exactly.

I would love some feedback.

I can provide you an alternative clean approach to rotate a square matrix 90 degree.

step 1: swap the element across diagonal. step 2: horizontally mirror image the elements

you got your rotated matrix.

Also you may play around horizontal vs vertical mirror image, based on in which direction you need to rotate the matrix.

eg

在此处输入图像描述

you got your 90° rotated matrix

Your are having indexing issue. Let's examine part of your code:

for j in range(left, right - 1):
    top_left = matrix[top][j]
    top_right = matrix[j][right - 1]
    bottom_right = matrix[bottom - 1][right - (j + 1)]

Consider what happens when j takes value right-2 . You will extract an entry from the column right - (j+1) = right - (right-2+1)=1 . That is regardless of which layer you are in, you will extract from the 1 -th column. You need to adjust back to the starting point of the layer, that is rather than right - (j+1) -th column, you need to access left + right - (j+1) -th column. Furthermore, notice that left + right is actually a constant, it is equal to the length of the matrix. You can take advantage of the negative indexing in Python and access -(j+1) -th column instead.

Also, we are already told that it is a square matrix, so top and left is always the same and bottom and right are always equal.

Here is a code that works performing the correction that I mentioned above:

def rotate(self, matrix: List[List[int]]) -> None:
    """
    Do not return anything, modify matrix in-place instead.
    """
    top = 0
    bottom = len(matrix)
    total_layers = round(bottom / 2)

    for i in range(0, total_layers):
        for j in range(top, bottom - 1):
            top_left = matrix[top][j]
            top_right = matrix[j][bottom - 1]
            bottom_right = matrix[bottom - 1][ - (j + 1)]
            bottom_left = matrix[- (1+j)][top]
            matrix[top][j] = bottom_left
            matrix[j][bottom-1] = top_left 
            matrix[bottom - 1][- (j + 1)] = top_right
            matrix[- (1 + j)][top] = bottom_right
        top += 1
        bottom -= 1

The next approach chooses left upper quarter of matrix, stores an element from this quarter and rearranges corresponding elements from other quarters in cyclic manner

def rotate_image(matrix):
    n = len(matrix)
    for i in range(0, (n + 1) // 2):
        for j in range(0, n // 2):
            storage = matrix[i][j]
            matrix[i][j] = matrix[n - j - 1][i]
            matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1]
            matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1]
            matrix[j][n - i - 1] = storage
    for i in range(len(matrix)):
        print(matrix[i])

mt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

rotate_image(mt)
print()

mt = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21,22, 23,24,25]]

rotate_image(mt)

[13, 9, 5, 1]
[14, 10, 6, 2]
[15, 11, 7, 3]
[16, 12, 8, 4]

[21, 16, 11, 6, 1]
[22, 17, 12, 7, 2]
[23, 18, 13, 8, 3]
[24, 19, 14, 9, 4]
[25, 20, 15, 10, 5]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM