Rotate a Matrix k Times Counterclockwise

Last Updated : 23 Jul, 2025

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

Examples: 

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

Input : k = 2, mat[][] =
{{1, 2, 3, 4},
{10, 11, 12, 5},
{9, 8, 7, 6}}
Output: mat[][] =
{{3, 4, 5, 6},
{2, 11, 12, 7},
{1, 10, 9, 8}}

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

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

C++
#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 counterclockwise
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 column
        prev = mat[row][col + 1];

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

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

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

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

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

    int k = 2;  // 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;
}

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[], 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.begin() + start + kNew);
        reverse(temp.begin() + start + kNew, temp.begin() + temp.size());
        reverse(temp.begin() + start, temp.begin() + temp.size());
    }

    // 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.*;

public class Main {
    static final int MAX = 100;

    // Fills temp array into mat[][] using spiral order
    // traversal.
    static void FillSpiral(int[][] mat, int m, int n,
                           int[] temp)
    {
        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++;
            }
        }
    }

    static void SpiralRotate(int[][] mat, int M, int N,
                             int k)
    {
        // Create a temporary array to store the result
        int[] temp = new int[M * N];

        int m = M, n = N, s = 0, l = 0;
        // Initialize end position of current ring
        int tIdx = 0;
        int start = 0;
        while (s < m && l < n) {
            int end = start;
            // copy the first row from the remaining rows
            for (int i = l; i < n; ++i) {
                temp[tIdx++] = mat[s][i];
                end++;
            }
            s++;
            // copy the last column from the remaining
            // columns
            for (int i = s; i < m; ++i) {
                temp[tIdx++] = mat[i][n - 1];
                end++;
            }
            n--;
            // copy the last row from the remaining rows
            if (s < m) {
                for (int i = n - 1; i >= l; --i) {
                    temp[tIdx++] = mat[m - 1][i];
                    end++;
                }
                m--;
            }
            if (l < n) {
                for (int i = m - 1; i >= s; --i) {
                    temp[tIdx++] = mat[i][l];
                    end++;
                }
                l++;
            }
            // if elements in current ring greater than k
            // then rotate elements of current ring
            if (end - start > k) {
              // Rotate current ring using reversal
            // algorithm for rotation
                reverseArray(temp, start, start + k - 1);
                reverseArray(temp, start + k, end - 1);
                reverseArray(temp, start, end - 1);

                start = end;
            }
        }
        // Fill temp array in original matrix.
        FillSpiral(mat, M, N, temp);
    }
    // Reverse Array
    static void reverseArray(int[] arr, int start, int end)
    {
        while (start < end) {
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
            start++;
            end--;
        }
    }

    // Driver code
    public static void main(String[] args)
    {

        int M = 4, N = 4, k = 3;
        int[][] mat = { { 1, 2, 3, 4 },
                        { 5, 6, 7, 8 },
                        { 9, 10, 11, 12 },
                        { 13, 14, 15, 16 } };

        SpiralRotate(mat, M, N, k);

        for (int i = 0; i < M; i++) {
            for (int j = 0; j < N; j++) {
                System.out.print(mat[i][j] + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python program to rotate individual rings by k in
# spiral order traversal.
MAX = 100

# Fills temp array into mat[][] using spiral order
# traversal.
def fillSpiral(mat, m, n, temp):
    i, k, l = 0, 0, 0
    tIdx = 0  # Index in temp array
    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

# Rotates the individual rings in spiral order
def spiralRotate(mat, M, N, k):
    # Create a temporary array to store the result
    temp = [0] * (M*N)

    m, n, s, l = M, N, 0, 0
    start = 0  # Start position of current ring
    tIdx = 0  # Index in temp
    while s < m and l < n:
        # Initialize end position of current ring
        end = start

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

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

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

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

        # if elements in current ring greater than k then rotate elements of current ring
        if end-start > k:
            # Rotate current ring using reversal algorithm for rotation
            temp[start:start+k], temp[start+k:end] = reversed(temp[start:start+k]), reversed(temp[start+k:end])
            temp[start:end] = reversed(temp[start:end])

            # Reset start for next ring
            start = end

    # Fill temp array in original matrix.
    fillSpiral(mat, M, N, temp)

# Driver program to run the case
if __name__ == "__main__":
    M = 4
    N = 4
    k = 3
    mat = [[1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
    [13, 14, 15, 16]]
    
    spiralRotate(mat, M, N, k)

    # print modified matrix
    for i in range(M):
        for j in range(N):
            print(mat[i][j], end=" ")
        print()
        
# This code is contributed by Prince Kumar
C#
// C# program to rotate individual rings by k in
// spiral order traversal.
using System;

class Program
{
    const int MAX = 100;
// Fills temp array into mat[][] using spiral order
// traversal.
    static void FillSpiral(int[,] mat, int m, int n, int[] temp)
    {
        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++;
            }
        }
    }

    static void SpiralRotate(int[,] mat, int M, int N, int k)
    {
       // Create a temporary array to store the result
        int[] temp = new int[M * N];

        int m = M, n = N, s = 0, l = 0;
    // Initialize end position of current ring
        int tIdx = 0;
        int start = 0;
        while (s < m && l < n)
        {
            int end = start;
 // copy the first row from the remaining rows
            for (int i = l; i < n; ++i)
            {
                temp[tIdx++] = mat[s, i];
                end++;
            }
            s++;

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

            if (l < n)
            {
                for (int i = m - 1; i >= s; --i)
                {
                    temp[tIdx++] = mat[i, l];
                    end++;
                }
                l++;
            }
  // if elements in current ring greater than
        // k then rotate elements of current ring
            if (end - start > k)
            {
                // Rotate current ring using reversal
            // algorithm for rotation
                Array.Reverse(temp, start, k);
                Array.Reverse(temp, start + k, end - start - k);
                Array.Reverse(temp, start, end - start);

                start = end;
            }
        }
 // Fill temp array in original matrix.
        FillSpiral(mat, M, N, temp);
    }
// Driver program to run the case
    static void Main(string[] args)
    {
       // Your C++ Code
        int M = 4, N = 4, k = 3;
        int[,] mat = { { 1, 2, 3, 4 },
                       { 5, 6, 7, 8 },
                       { 9, 10, 11, 12 },
                       { 13, 14, 15, 16 } };

        SpiralRotate(mat, M, N, k);

        for (int i = 0; i < M; i++)
        {
            for (int j = 0; j < N; j++)
            {
                Console.Write(mat[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// JavaScript program to rotate individual rings by k in
// spiral order traversal.
const MAX = 100;
// Fills temp array into mat[][] using spiral order traversal.

function fillSpiral(mat, m, n, temp) {
  let i = 0,
    k = 0,
    l = 0;
  let tIdx = 0; // Index in temp array
  while (k < m && l < n) {
  // first row from the remaining rows
    for (i = l; i < n; i++) {
      mat[k][i] = temp[tIdx];
      tIdx++;
    }
    k++;

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

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

    if (l < n) {
      for (i = m - 1; i >= k; i--) {
        mat[i][l] = temp[tIdx];
        tIdx++;
      }
      l++;
    }
  }
}
// Rotates the individual rings in spiral order

function spiralRotate(mat, M, N, k) {
// Create a temporary array to store the result

  const temp = new Array(M * N).fill(0);

  let m = M,
    n = N,
    s = 0,
    l = 0;
  let start = 0; // Start position of current ring
  let tIdx = 0; // Index in temp
  while (s < m && l < n) {
  // Initialize end position of current ring
    let end = start;
    // copy the first row from the remaining rows

    for (let i = l; i < n; i++) {
    
      temp[tIdx] = mat[s][i];
      tIdx++;
      end++;
    }
    s++;
     // copy the last column from the remaining columns

    for (let i = s; i < m; i++) {
      temp[tIdx] = mat[i][n - 1];
      tIdx++;
      end++;
    }
    n--;
     // copy the last row from the remaining rows

    if (s < m) {
      for (let i = n - 1; i >= l; i--) {
        temp[tIdx] = mat[m - 1][i];
        tIdx++;
        end++;
      }
      m--;
    }
// copy the first column from the remaining columns
    if (l < n) {
      for (let i = m - 1; i >= s; i--) {
        temp[tIdx] = mat[i][l];
        tIdx++;
        end++;
      }
      l++;
    }
     // if elements in current ring greater than k then rotate elements of current ring
    if (end - start > k) {
    // Rotate current ring using reversal algorithm for rotation
      temp.splice(start, k, ...temp.slice(start, start + k).reverse());
      temp.splice(start + k, end - start - k, ...temp.slice(start + k, end).reverse());
      temp.splice(start, end - start, ...temp.slice(start, end).reverse());

      start = end;
    }
  }
  fillSpiral(mat, M, N, temp);
}

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

spiralRotate(mat, M, N, k);
  // print modified matrix

for (let i = 0; i < M; i++) {
  for (let j = 0; j < N; j++) {
    process.stdout.write(mat[i][j] + " ");
  }
  console.log();
}
// This code is generated by chetan bargal

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


Comment