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 4Input : 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++ 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 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 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# 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 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..
#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;
}
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();
}
}
}
# 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)))
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();
}
}
}
// 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