Array Rotation

Question statement

You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise) in-place

Pasted image 20230505121144.png

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]

Pasted image 20230505121227.png

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

Example: https://leetcode.com/problems/rotate-image/

Approach 1: Loop using 2 pointers

Time complexity: $O(n)$:

  • Looping from the outer ring to the inner ring. Each cell is written once
    Space complexity: $O(1)$:
  • In-place modification

Pasted image 20230505131612.png

The idea is we have j to loop for each element. Whereas i to go level-by-level.

Therefore, the start elements will be from i to n-i with n is the last element. This will be the boundary of our loop: [i, n-i].

class App:
    def rotate(self, matrix: List[List[int]]) -> None:
        if len(matrix) == 0: return []
        if len(matrix) != len(matrix[0]):
            raise RuntimeError("Invalid dimension")
        
        n = len(matrix) - 1
        for i in range(len(matrix)): # Loop through level from outside to inside
            for j in range(i, len(matrix) - i - 1): # each element inside the ring
                top = matrix[i][j]
                right = matrix[j][n - i]
                bottom = matrix[n - i][n - j]
                left = matrix[n - j][i]
                
                matrix[j][n - i] = top
                matrix[n - i][n - j] = right
                matrix[n - j][i] = bottom
                matrix[i][j] = left

        return matrix

Approach 2: Loop using 4 pointers

The idea is we have 4 pointers:

  • top, bottom, left, right
l     r
* * * * t
* * * *
* * * *
* * * * b

we can then keep moving these 4 pointers to swap to each other

Time complexity: $O(n)$

  • Loop using 4 pointers in 4 corners, each cell is written once
    Space complexity: O(1)
  • In place modification
 def rotate(self, matrix: List[List[int]]) -> None:
        if len(matrix) == 0: return []
        if len(matrix) != len(matrix[0]):
            raise RuntimeError("Invalid dimension")
        
        top, bottom = 0, len(matrix) - 1
        left, right = 0, len(matrix) - 1
        
        while (left < right):
            for i in range(right - left): 
                topElement = matrix[top][left + i] # row is fixed to top, column moves
                rightElement = matrix[top + i][right] # column is fixed to right, row moves
                bottomElement = matrix[bottom][right - i] # row is fixed to bottom, column moves
                leftElement = matrix[bottom - i][left] # column is fixed to left, row moves
                
                matrix[top + i][right] = topElement
                matrix[bottom][right - i] = rightElement
                matrix[bottom - i][left] = bottomElement
                matrix[top][left + i] = leftElement
                
                
            top += 1
            left += 1
            right -= 1
            bottom -= 1
        
        return matrix