Open In App

Rotate a Matrix k Times Clockwise

Last Updated : 18 Oct, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given a matrix of order m*n and a value k, the task is to rotate each ring of the matrix clockwise by k.

Examples:

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

Input : k = 2
1 2 3 4
10 11 12 5
9 8 7 6
Output:
9 10 1 2
8 11 12 3
7 6 5 4

Naive Solution - O(k*m*n) Time and O(1) Space

We simply use the solution of clockwise rotate by one and call it in a loop.

C++
// C++ program to rotate matrix k
// times by Naive approach
#include <bits/stdc++.h>
using namespace std;

// Used inside rotateMatrixKTimes()
void rotateMatrix(vector<vector<int>>& mat);

// Function to rotate the matrix k times
void rotateMatrixKTimes(vector<vector<int>>& mat, int k) {    
    for (int i = 0; i < k; i++) {
        rotateMatrix(mat);
    }
}

// Function to rotate a matrix represented by
// a vector of vectors
void rotateMatrix(vector<vector<int>>& mat) {
    
    int m = mat.size();
    int n = mat[0].size();
    int row = 0, col = 0;
    int prev, curr;

    // Rotate the matrix in layers
    while (row < m && col < n) {
        if (row + 1 == m || col + 1 == n)
            break;

        // Store the first element of the next row
        prev = mat[row + 1][col];

        // Move elements of the first row
        for (int i = col; i < n; i++) {
            curr = mat[row][i];
            mat[row][i] = prev;
            prev = curr;
        }
        row++;

        // Move elements of the last column
        for (int i = row; i < m; i++) {
            curr = mat[i][n - 1];
            mat[i][n - 1] = prev;
            prev = curr;
        }
        n--;

        // Move elements of the last row
        if (row < m) {
            for (int i = n - 1; i >= col; i--) {
                curr = mat[m - 1][i];
                mat[m - 1][i] = prev;
                prev = curr;
            }
        }
        m--;

        // Move elements of the first column
        if (col < n) {
            for (int i = m - 1; i >= row; i--) {
                curr = mat[i][col];
                mat[i][col] = prev;
                prev = curr;
            }
        }
        col++;
    }
}

int main() {
    vector<vector<int>> mat = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };

    int k = 5;  // Rotate the matrix 2 times
    rotateMatrixKTimes(mat, k);

    // Print the rotated matrix
    for (auto& r : mat) {
        for (int val : r)
            cout << val << " ";
        cout << endl;
    }

    return 0;
}
Java
// Java program to rotate matrix k
// times by Naive approach
class GfG {
  
  	// Function to rotate a matrix represented 
	// by a vector of vectors
    void rotateMatrix(int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;
        int row = 0, col = 0;
        int prev, curr;

        while (row < m && col < n) {
            if (row + 1 == m || col + 1 == n) break;

            prev = mat[row + 1][col];

            // Move elements of the first row
            for (int i = col; i < n; i++) {
                curr = mat[row][i];
                mat[row][i] = prev;
                prev = curr;
            }
            row++;

            // Move elements of the last column
            for (int i = row; i < m; i++) {
                curr = mat[i][n - 1];
                mat[i][n - 1] = prev;
                prev = curr;
            }
            n--;

            // Move elements of the last row
            if (row < m) {
                for (int i = n - 1; i >= col; i--) {
                    curr = mat[m - 1][i];
                    mat[m - 1][i] = prev;
                    prev = curr;
                }
            }
            m--;

            // Move elements of the first column
            if (col < n) {
                for (int i = m - 1; i >= row; i--) {
                    curr = mat[i][col];
                    mat[i][col] = prev;
                    prev = curr;
                }
            }
            col++;
        }
    }
	// Function to rotate the matrix k times
    void rotateMatrixKTimes(int[][] mat, int k) {
        for (int i = 0; i < k; i++) {
            rotateMatrix(mat);
        }
    }

    public static void main(String[] args) {
        GfG solution = new GfG();
        int[][] mat = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 16}
        };

        int k = 5; // Rotate the matrix 2 times
        solution.rotateMatrixKTimes(mat, k);

        // Print the rotated matrix without using Arrays.toString
        for (int[] row : mat) {
            for (int val : row) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python program to rotate matrix k
# times by Naive approach

# Function to rotate a matrix represented 
# by a vector of vectors
def rotateMatrix(mat):
    m, n = len(mat), len(mat[0])
    row, col = 0, 0
    
    while row < m and col < n:
        if row + 1 == m or col + 1 == n:
            break
        
        prev = mat[row + 1][col]

        # Move elements of the first row
        for i in range(col, n):
            curr = mat[row][i]
            mat[row][i] = prev
            prev = curr
        row += 1

        # Move elements of the last column
        for i in range(row, m):
            curr = mat[i][n - 1]
            mat[i][n - 1] = prev
            prev = curr
        n -= 1

        # Move elements of the last row
        if row < m:
            for i in range(n - 1, col - 1, -1):
                curr = mat[m - 1][i]
                mat[m - 1][i] = prev
                prev = curr
        m -= 1

        # Move elements of the first column
        if col < n:
            for i in range(m - 1, row - 1, -1):
                curr = mat[i][col]
                mat[i][col] = prev
                prev = curr
        col += 1
       
# Function to rotate the matrix k times
def rotateMatrixKTimes(mat, k):
    for i in range(k):
        rotateMatrix(mat)

if __name__ == "__main__":
    mat = [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12],
        [13, 14, 15, 16]
    ]

    k = 5  # Rotate the matrix 2 times
    rotateMatrixKTimes(mat, k)

    # Print the rotated matrix
    for row in mat:
        print(" ".join(map(str, row)))
C#
//  C# to rotate matrix k
// times by Naive approach
using System;

class GfG {
  	// Function to rotate a matrix represented 
	// by a vector of vectors
    void RotateMatrix(int[,] mat) {
        int m = mat.GetLength(0);
        int n = mat.GetLength(1);
        int row = 0, col = 0;

        while (row < m && col < n) {
            if (row + 1 == m || col + 1 == n) break;

            int prev = mat[row + 1, col];

            // Move elements of the first row
            for (int i = col; i < n; i++) {
                int curr = mat[row, i];
                mat[row, i] = prev;
                prev = curr;
            }
            row++;

            // Move elements of the last column
            for (int i = row; i < m; i++) {
                int curr = mat[i, n - 1];
                mat[i, n - 1] = prev;
                prev = curr;
            }
            n--;

            // Move elements of the last row
            if (row < m) {
                for (int i = n - 1; i >= col; i--) {
                    int curr = mat[m - 1, i];
                    mat[m - 1, i] = prev;
                    prev = curr;
                }
            }
            m--;

            // Move elements of the first column
            if (col < n) {
                for (int i = m - 1; i >= row; i--) {
                    int curr = mat[i, col];
                    mat[i, col] = prev;
                    prev = curr;
                }
            }
            col++;
        }
    }
	
  	// Function to rotate the matrix k times
    void RotateMatrixKTimes(int[,] mat, int k) {
        for (int i = 0; i < k; i++) {
            RotateMatrix(mat);
        }
    }

    static void Main(string[] args) {
        GfG solution = new GfG();
        int[,] mat = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 },
            { 13, 14, 15, 16 }
        };

        int k = 5; // Rotate the matrix 2 times
        solution.RotateMatrixKTimes(mat, k);

        // Print the rotated matrix
        for (int i = 0; i < mat.GetLength(0); i++) {
            for (int j = 0; j < mat.GetLength(1); j++) {
                Console.Write(mat[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// JavaScript program to rotate matrix k
// times by Naive approach

// Function to rotate a matrix represented
// by a vector of vectors
function rotateMatrix(mat) {
    let m = mat.length;
    let n = mat[0].length;
    let row = 0, col = 0;

    while (row < m && col < n) {
        if (row + 1 === m || col + 1 === n) break;

        let prev = mat[row + 1][col];

        // Move elements of the first row
        for (let i = col; i < n; i++) {
            let curr = mat[row][i];
            mat[row][i] = prev;
            prev = curr;
        }
        row++;

        // Move elements of the last column
        for (let i = row; i < m; i++) {
            let curr = mat[i][n - 1];
            mat[i][n - 1] = prev;
            prev = curr;
        }
        n--;

        // Move elements of the last row
        if (row < m) {
            for (let i = n - 1; i >= col; i--) {
                let curr = mat[m - 1][i];
                mat[m - 1][i] = prev;
                prev = curr;
            }
        }
        m--;

        // Move elements of the first column
        if (col < n) {
            for (let i = m - 1; i >= row; i--) {
                let curr = mat[i][col];
                mat[i][col] = prev;
                prev = curr;
            }
        }
        col++;
    }
}

// Function to rotate the matrix k times
function rotateMatrixKTimes(mat, k) {
    for (let i = 0; i < k; i++) {
        rotateMatrix(mat);
    }
}

const mat = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16]
];
const k = 5; 
rotateMatrixKTimes(mat, k);

// Print the rotated matrix
mat.forEach(row => {
    console.log(row.join(" "));
});

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

Efficient Solution - O(m*n) Time and O(m*n) Space

The idea is to traverse matrix in spiral form. Here is the algorithm to solve this problem : 

  • Make an auxiliary array temp[] of size m*n.
  • Start traversing matrix in spiral form and store elements of current ring in temp[] array. While storing the elements in temp, keep track of starting and ending positions of current ring.
  • For every ring that is being stored in temp[], right rotate that subarray temp[]
  • Repeat this process for each ring of matrix.
  • In last traverse matrix again spirally and copy elements of temp[] array to matrix..
C++
#include<bits/stdc++.h>
using namespace std;

// Fills temp array into mat using spiral order traversal.
// Used inside the main function spiralRotate()
void fillSpiral(vector<vector<int>>& mat, vector<int>& temp);

void spiralRotate(vector<vector<int>>& mat, int k) {
    int m = mat.size();
    int n = mat[0].size();

    // Temporary array to store elements in the spiral order
    vector<int> temp;  

    int s = 0, l = 0;

    while (s < m && l < n) {
      
        // Record the start position of the current ring
        int start = temp.size(); 

        // copy the first row from the remaining rows
        for (int i = l; i < n; ++i)
            temp.push_back(mat[s][i]);
        s++;

        // copy the last column from the remaining columns
        for (int i = s; i < m; ++i)
            temp.push_back(mat[i][n - 1]);
        n--;

        // copy the last row from the remaining rows
        if (s < m) {
            for (int i = n - 1; i >= l; --i)
                temp.push_back(mat[m - 1][i]);
            m--;
        }

        // copy the first column from the remaining columns
        if (l < n) {
            for (int i = m - 1; i >= s; --i)
                temp.push_back(mat[i][l]);
            l++;
        }

        int ringSize = temp.size() - start;

        // Adjust k to rotate only within the current ring
        int kNew = k % ringSize;

        // Rotate the current ring using the reversal algorithm
       	reverse(temp.begin() + start, temp.end());              
        reverse(temp.begin() + start, temp.begin() + start + kNew);  
        reverse(temp.begin() + start + kNew, temp.end()); 
    }

    // Fill the matrix back using the temp array
    fillSpiral(mat, temp);
}

// Fills temp array into mat using spiral order traversal.
void fillSpiral(vector<vector<int>>& mat, vector<int>& temp) {
    int m = mat.size();
    int n = mat[0].size();
    int k = 0, l = 0;
    int tIdx = 0;  // Index in temp array

    while (k < m && l < n) {
        // first row from the remaining rows
        for (int i = l; i < n; ++i)
            mat[k][i] = temp[tIdx++];
        k++;

        // last column from the remaining columns
        for (int i = k; i < m; ++i)
            mat[i][n - 1] = temp[tIdx++];
        n--;

        // last row from the remaining rows
        if (k < m) {
            for (int i = n - 1; i >= l; --i)
                mat[m - 1][i] = temp[tIdx++];
            m--;
        }

        // first column from the remaining columns
        if (l < n) {
            for (int i = m - 1; i >= k; --i)
                mat[i][l] = temp[tIdx++];
            l++;
        }
    }
}

int main() {
    int k = 5;
    vector<vector<int>> mat = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };

    spiralRotate(mat, k);
  
    for (auto& row : mat) {
        for (int val : row)
            cout << val << " ";
        cout << endl;
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

class GfG {
  
  	// Fills temp array into mat using spiral order traversal.
	// Used inside the main function spiralRotate()
    void fillSpiral(int[][] mat, List<Integer> temp) {
        int m = mat.length;
        int n = mat[0].length;
        int k = 0, l = 0;
      	
      	// Index in temp array
        int tIdx = 0;  

        while (k < m && l < n) {
          
            // first row from the remaining rows
            for (int i = l; i < n; ++i)
                mat[k][i] = temp.get(tIdx++);
            k++;

            // last column from the remaining columns
            for (int i = k; i < m; ++i)
                mat[i][n - 1] = temp.get(tIdx++);
            n--;

            // last row from the remaining rows
            if (k < m) {
                for (int i = n - 1; i >= l; --i)
                    mat[m - 1][i] = temp.get(tIdx++);
                m--;
            }

            // first column from the remaining columns
            if (l < n) {
                for (int i = m - 1; i >= k; --i)
                    mat[i][l] = temp.get(tIdx++);
                l++;
            }
        }
    }

    void spiralRotate(int[][] mat, int k) {
        int m = mat.length;
        int n = mat[0].length;

        // Temporary array to store elements in the spiral order
        List<Integer> temp = new ArrayList<>();  

        int s = 0, l = 0;

        while (s < m && l < n) {
          
            // Record the start position of the current ring
            int start = temp.size(); 

            // copy the first row from the remaining rows
            for (int i = l; i < n; ++i)
                temp.add(mat[s][i]);
            s++;

            // copy the last column from the remaining columns
            for (int i = s; i < m; ++i)
                temp.add(mat[i][n - 1]);
            n--;

            // copy the last row from the remaining rows
            if (s < m) {
                for (int i = n - 1; i >= l; --i)
                    temp.add(mat[m - 1][i]);
                m--;
            }

            // copy the first column from the remaining columns
            if (l < n) {
                for (int i = m - 1; i >= s; --i)
                    temp.add(mat[i][l]);
                l++;
            }

            int ringSize = temp.size() - start;

            // Adjust k to rotate only within the current ring
            int kNew = k % ringSize;

            // Rotate the current ring using the reversal algorithm
            reverse(temp, start, temp.size()); 
            reverse(temp, start, start + kNew);
            reverse(temp, start + kNew, temp.size()); 
        }

        // Fill the matrix back using the temp array
        fillSpiral(mat, temp);
    }

    void reverse(List<Integer> arr, int start, int end) {
        while (start < end) {
            int temp = arr.get(start);
            arr.set(start, arr.get(end - 1));
            arr.set(end - 1, temp);
            start++;
            end--;
        }
    }

    public static void main(String[] args) {
        GfG solution = new GfG();
        int k = 5;
        int[][] mat = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 16}
        };

        solution.spiralRotate(mat, k);
  
        for (int[] row : mat) {
            for (int val : row)
                System.out.print(val + " ");
            System.out.println();
        }
    }
}
Python
# Fills temp array into mat using spiral order traversal.
# Used inside the main function spiralRotate()
def fillSpiral(mat, temp):
    m, n = len(mat), len(mat[0])
    k, l = 0, 0
    
    # Index in temp array
    tIdx = 0  

    while k < m and l < n:
      
        # first row from the remaining rows
        for i in range(l, n):
            mat[k][i] = temp[tIdx]
            tIdx += 1
        k += 1

        # last column from the remaining columns
        for i in range(k, m):
            mat[i][n - 1] = temp[tIdx]
            tIdx += 1
        n -= 1

        # last row from the remaining rows
        if k < m:
            for i in range(n - 1, l - 1, -1):
                mat[m - 1][i] = temp[tIdx]
                tIdx += 1
            m -= 1

        # first column from the remaining columns
        if l < n:
            for i in range(m - 1, k - 1, -1):
                mat[i][l] = temp[tIdx]
                tIdx += 1
            l += 1

def spiralRotate(mat, k):
    m, n = len(mat), len(mat[0])
    
    # Temporary array to store elements in the spiral order
    temp = []  

    s, l = 0, 0

    while s < m and l < n:
      	
        # Record the start position of the current ring
        start = len(temp)

        # copy the first row from the remaining rows
        for i in range(l, n):
            temp.append(mat[s][i])
        s += 1

        # copy the last column from the remaining columns
        for i in range(s, m):
            temp.append(mat[i][n - 1])
        n -= 1

        # copy the last row from the remaining rows
        if s < m:
            for i in range(n - 1, l - 1, -1):
                temp.append(mat[m - 1][i])
            m -= 1

        # copy the first column from the remaining columns
        if l < n:
            for i in range(m - 1, s - 1, -1):
                temp.append(mat[i][l])
            l += 1

        ringSize = len(temp) - start

        # Adjust k to rotate only within the current ring
        kNew = k % ringSize

        # Rotate the current ring using the reversal algorithm
        temp[start:] = reversed(temp[start:])  
        temp[start:start + kNew] = reversed(temp[start:start + kNew])  
        temp[start + kNew:] = reversed(temp[start + kNew:])  

    # Fill the matrix back using the temp array
    fillSpiral(mat, temp)

if __name__ == "__main__":
    k = 5
    mat = [
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12],
        [13, 14, 15, 16]
    ]

    spiralRotate(mat, k)

    for row in mat:
        print(" ".join(map(str, row)))
C#
using System;
using System.Collections.Generic;

class GfG {
  
  	// Fills temp array into mat using spiral order traversal.
	// Used inside the main function spiralRotate()
    void FillSpiral(int[,] mat, List<int> temp) {
        int m = mat.GetLength(0);
        int n = mat.GetLength(1);
        int k = 0, l = 0;
      
      	// Index in temp array
        int tIdx = 0;  

        while (k < m && l < n) {
          
            // first row from the remaining rows
            for (int i = l; i < n; ++i)
                mat[k, i] = temp[tIdx++];
            k++;

            // last column from the remaining columns
            for (int i = k; i < m; ++i)
                mat[i, n - 1] = temp[tIdx++];
            n--;

            // last row from the remaining rows
            if (k < m) {
                for (int i = n - 1; i >= l; --i)
                    mat[m - 1, i] = temp[tIdx++];
                m--;
            }

            // first column from the remaining columns
            if (l < n) {
                for (int i = m - 1; i >= k; --i)
                    mat[i, l] = temp[tIdx++];
                l++;
            }
        }
    }

    void SpiralRotate(int[,] mat, int k) {
        int m = mat.GetLength(0);
        int n = mat.GetLength(1);

        // Temporary array to store elements in the spiral order
        List<int> temp = new List<int>();  

        int s = 0, l = 0;

        while (s < m && l < n) {
          
            // Record the start position of the current ring
            int start = temp.Count; 

            // copy the first row from the remaining rows
            for (int i = l; i < n; ++i)
                temp.Add(mat[s, i]);
            s++;

            // copy the last column from the remaining columns
            for (int i = s; i < m; ++i)
                temp.Add(mat[i, n - 1]);
            n--;

            // copy the last row from the remaining rows
            if (s < m) {
                for (int i = n - 1; i >= l; --i)
                    temp.Add(mat[m - 1, i]);
                m--;
            }

            // copy the first column from the remaining columns
            if (l < n) {
                for (int i = m - 1; i >= s; --i)
                    temp.Add(mat[i, l]);
                l++;
            }

            int ringSize = temp.Count - start;

            // Adjust k to rotate only within the current ring
            int kNew = k % ringSize;

            // Rotate the current ring using the reversal algorithm
            Reverse(temp, start, temp.Count);        
            Reverse(temp, start, start + kNew);      
            Reverse(temp, start + kNew, temp.Count);
        }

        // Fill the matrix back using the temp array
        FillSpiral(mat, temp);
    }

    void Reverse(List<int> arr, int start, int end) {
        while (start < end) {
            int temp = arr[start];
            arr[start] = arr[end - 1];
            arr[end - 1] = temp;
            start++;
            end--;
        }
    }

    static void Main(string[] args) {
        GfG solution = new GfG();
        int k = 5;
        int[,] mat = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 },
            { 13, 14, 15, 16 }
        };

        solution.SpiralRotate(mat, k);
  
        for (int i = 0; i < mat.GetLength(0); i++) {
            for (int j = 0; j < mat.GetLength(1); j++) {
                Console.Write(mat[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// Fills temp array into mat using spiral order traversal.
// Used inside the main function spiralRotate()
function fillSpiral(mat, temp) {
    let m = mat.length;
    let n = mat[0].length;
    let k = 0, l = 0;
    // Index in temp array
    let tIdx = 0;  

    while (k < m && l < n) {
        // first row from the remaining rows
        for (let i = l; i < n; ++i)
            mat[k][i] = temp[tIdx++];
        k++;

        // last column from the remaining columns
        for (let i = k; i < m; ++i)
            mat[i][n - 1] = temp[tIdx++];
        n--;

        // last row from the remaining rows
        if (k < m) {
            for (let i = n - 1; i >= l; --i)
                mat[m - 1][i] = temp[tIdx++];
            m--;
        }

        // first column from the remaining columns
        if (l < n) {
            for (let i = m - 1; i >= k; --i)
                mat[i][l] = temp[tIdx++];
            l++;
        }
    }
}

function spiralRotate(mat, k) {
    let m = mat.length;
    let n = mat[0].length;

    // Temporary array to store elements in the spiral order
    let temp = [];  

    let s = 0, l = 0;

    while (s < m && l < n) {
        // Record the start position of the current ring
        let start = temp.length; 

        // copy the first row from the remaining rows
        for (let i = l; i < n; ++i)
            temp.push(mat[s][i]);
        s++;

        // copy the last column from the remaining columns
        for (let i = s; i < m; ++i)
            temp.push(mat[i][n - 1]);
        n--;

        // copy the last row from the remaining rows
        if (s < m) {
            for (let i = n - 1; i >= l; --i)
                temp.push(mat[m - 1][i]);
            m--;
        }

        // copy the first column from the remaining columns
        if (l < n) {
            for (let i = m - 1; i >= s; --i)
                temp.push(mat[i][l]);
            l++;
        }

        let ringSize = temp.length - start;

        // Adjust k to rotate only within the current ring
        let kNew = k % ringSize;

        // Rotate the current ring using the reversal algorithm
        reverse(temp, start, temp.length);        
        reverse(temp, start, start + kNew);       
        reverse(temp, start + kNew, temp.length);

    }

    // Fill the matrix back using the temp array
    fillSpiral(mat, temp);
}

function reverse(arr, start, end) {
    while (start < end) {
        [arr[start], arr[end - 1]] = [arr[end - 1], arr[start]];
        start++;
        end--;
    }
}

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

spiralRotate(mat, k);

for (const row of mat) {
    console.log(row.join(" "));
}

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



Article Tags :
Practice Tags :

Similar Reads