Cyclically Rotating a Grid solution and explanation
9 more videos on this problem
Cyclically Rotating a Grid | Simplified and Easy | Dry Run | Leetcode 1914 | codestorywithMIKcodestorywithMIK · 20:56 · 5K views
Leetcode-Cyclically Rotating a GridCoding For Dummies · 13:00 · 1K views
Daily Leetcode #2230: May 09, 2026 - 1914. Cyclically Rotating a GridProgramming Live with Larry · 20:56 · 991 views
1914. Cyclically Rotating a Grid (Leetcode Medium)Programming Live with Larry · 20:41 · 804 views
LeetCode Weekly Contest 247 Question 2: Cyclically Rotating a GridCoding Ninjas Webinars and Contest Editorials · 24:51 · 799 views
Cyclically Rotating a Grid | Leetcode 1914 | Java | Hindi | Detailed ExplanationKernel Queen 👑 · 11:55 · 762 views
1914. Cyclically Rotating a Grid | Leetcode Daily - PythonLeetcode Daily · 5:45 · 756 views
leetcode 1914 | Cyclically Rotating a Grid | Matrix Rotation | Leetcode POTD | DSA | Easy SolutionCode With Vick · 16:55 · 591 views
Cyclically Rotating a Grid | LeetCode 1914 - Pythonimpoldev · 9:17 · 424 views
Cyclically Rotating a Grid | LeetCode 1914Streak To Scale · 6:21 · 239 views
The problem
You are given an m x n integer matrix grid, where m and n are both even integers, and an integer k.
The matrix is composed of several layers, which is shown in the below image, where each color is its own layer:

A cyclic rotation of the matrix is done by cyclically rotating each layer in the matrix. To cyclically rotate a layer once, each element in the layer will take the place of the adjacent element in the counter-clockwise direction. An example rotation is shown below:
Return the matrix after applying k cyclic rotations to it.
Example 1:
Input: grid = [[40,10],[30,20]], k = 1 Output: [[10,20],[40,30]] Explanation: The figures above represent the grid at every state.
Example 2:
Input: grid = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], k = 2 Output: [[3,4,8,12],[2,11,10,16],[1,7,6,15],[5,9,13,14]] Explanation: The figures above represent the grid at every state.
Constraints:
m == grid.lengthn == grid[i].length2 <= m, n <= 50- Both
mandnare even integers. 1 <= grid[i][j] <= 50001 <= k <= 109
Approach overview
Problem Overview: You are given an m x n grid and an integer k. Each rectangular layer of the matrix must be rotated cyclically k times in the counter‑clockwise direction. The outer ring rotates independently from inner rings, so the main task is correctly identifying layer boundaries and moving elements along their perimeter.
Approach 1: Layered Rotation Method (O(m*n) time, O(min(m,n)) space)
Process the grid one layer at a time. For a layer defined by top, bottom, left, right boundaries, extract all elements along its perimeter into a temporary list. The number of effective rotations is k % perimeter_length, which avoids unnecessary full cycles. Rotate the list and write values back along the same perimeter order. Every cell is visited a constant number of times, so the total runtime is O(m*n) with O(perimeter) temporary storage per layer. This approach is straightforward and easy to debug because the rotation happens on a linear representation of the ring.
This technique works well for problems involving matrix layer traversal. The key insight is recognizing that each ring forms a circular array. Once converted to a list, cyclic rotation becomes a simple index shift.
Approach 2: Direct Coordinate Manipulation (O(m*n) time, O(1) space)
Instead of extracting elements, compute the final position of each element directly. For every cell, determine which layer it belongs to using its minimum distance from the grid edges. From that layer you can compute the perimeter length and the element's offset along the ring. After applying (offset + k) % perimeter, convert the new offset back into grid coordinates and place the value in the rotated position.
This method avoids building temporary arrays and performs rotation purely through coordinate math. It achieves O(1) extra space while still scanning the grid once for O(m*n) time. The tradeoff is more complex index calculations along the ring edges. Problems focused on array manipulation and simulation often benefit from this style of direct coordinate mapping.
Recommended for interviews: The layered rotation method is usually expected. It clearly demonstrates understanding of matrix layers and cyclic rotation using k % perimeter. The direct coordinate approach is more space‑efficient but involves heavier index math, so it is typically considered an optimization after explaining the layer‑based solution.
Approach 1: Layered Rotation Method
This approach involves extracting each layer of the matrix, performing a rotation on the linearized version, and then re-integrating the rotated data back into the matrix.
- Identify layers: These are rectangular paths from the outer boundary inward.
- Flatten the layer into a 1D array.
- Calculate the number of effective rotations using modulo operation since rotating a layer of size n by n leads back to the original layer.
- Perform the rotation on the flattened layer.
- Map the rotated 1D array back to its 2D layer position in the matrix.
def rotateGrid(grid, k):
m, n = len(grid), len(grid[0])
layers = min(m, n) // 2
for layer in range(layers):
elements = []
for i in range(layer, n - layer):
elements.append(grid[layer][i])
for i in range(layer + 1, m - layer):
elements.append(grid[i][n - layer - 1])
for i in range(n - layer - 2, layer - 1, -1):
elements.append(grid[m - layer - 1][i])
for i in range(m - layer - 2, layer, -1):
elements.append(grid[i][layer])
total_elements = len(elements)
k_mod = k % total_elements
elements = elements[-k_mod:] + elements[:-k_mod]
index = 0
for i in range(layer, n - layer):
grid[layer][i] = elements[index]
index += 1
for i in range(layer + 1, m - layer):
grid[i][n - layer - 1] = elements[index]
index += 1
for i in range(n - layer - 2, layer - 1, -1):
grid[m - layer - 1][i] = elements[index]
index += 1
for i in range(m - layer - 2, layer, -1):
grid[i][layer] = elements[index]
index += 1
return grid#include <vector>
using namespace std;
vector<vector<int>> rotateGrid(vector<vector<int>>& grid, int k) {
int m = grid.size(), n = grid[0].size();
int layers = min(m, n) / 2;
for (int layer = 0; layer < layers; ++layer) {
vector<int> elements;
for (int j = layer; j < n - layer; ++j) elements.push_back(grid[layer][j]);
for (int i = layer + 1; i < m - layer; ++i) elements.push_back(grid[i][n - layer - 1]);
for (int j = n - layer - 2; j >= layer; --j) elements.push_back(grid[m - layer - 1][j]);
for (int i = m - layer - 2; i > layer; --i) elements.push_back(grid[i][layer]);
int total_elements = elements.size();
k = k % total_elements;
rotate(elements.rbegin(), elements.rbegin() + k, elements.rend());
int index = 0;
for (int j = layer; j < n - layer; ++j) grid[layer][j] = elements[index++];
for (int i = layer + 1; i < m - layer; ++i) grid[i][n - layer - 1] = elements[index++];
for (int j = n - layer - 2; j >= layer; --j) grid[m - layer - 1][j] = elements[index++];
for (int i = m - layer - 2; i > layer; --i) grid[i][layer] = elements[index++];
}
return grid;
}This Python implementation follows the outlined approach. We loop through each layer, extract elements into a list, perform the rotation using slicing based on the effective k, and then re-map elements back to their respective positions.
Time Complexity: O(m * n) as each element is visited once. Space Complexity: O(max(m, n)) due to the storage of one layer's elements.
Approach 2: Direct Coordinate Manipulation
In this approach, we directly manipulate the matrix's coordinates without requiring additional storage for layers. This is achieved by calculating the next position directly based on the current position and number of rotations.
- Calculate total elements in a layer using its boundaries.
- For each element, calculate its final destination after k rotations using coordinate tracing.
- Use modulo operations to reduce computation and manage wrapping around of elements.
class Solution {
public int[][] rotateGrid(int[][] grid, int k) {
int m = grid.length, n = grid[0].length;
for (int layer = 0; layer < Math.min(m, n) / 2; ++layer) {
int elements = ((n - 2 * layer) + (m - 2 * layer - 1)) * 2;
int[] temp = new int[elements];
int index = 0;
for (int j = layer; j < n - layer; ++j) temp[index++] = grid[layer][j];
for (int i = layer + 1; i < m - layer; ++i) temp[index++] = grid[i][n - layer - 1];
for (int j = n - layer - 2; j >= layer; --j) temp[index++] = grid[m - layer - 1][j];
for (int i = m - layer - 2; i > layer; --i) temp[index++] = grid[i][layer];
k = k % elements;
index = elements - k;
for (int j = layer; j < n - layer; ++j) grid[layer][j] = temp[index++ % elements];
for (int i = layer + 1; i < m - layer; ++i) grid[i][n - layer - 1] = temp[index++ % elements];
for (int j = n - layer - 2; j >= layer; --j) grid[m - layer - 1][j] = temp[index++ % elements];
for (int i = m - layer - 2; i > layer; --i) grid[i][layer] = temp[index++ % elements];
}
return grid;
}
}function rotateGrid(grid, k) {
const m = grid.length, n = grid[0].length;
for (let layer = 0; layer < Math.min(m, n) / 2; layer++) {
const elements = [];
for (let j = layer; j < n - layer; j++) elements.push(grid[layer][j]);
for (let i = layer + 1; i < m - layer; i++) elements.push(grid[i][n - layer - 1]);
for (let j = n - layer - 2; j >= layer; j--) elements.push(grid[m - layer - 1][j]);
for (let i = m - layer - 2; i > layer; i--) elements.push(grid[i][layer]);
const len = elements.length;
k = k % len;
let index = len - k;
for (let j = layer; j < n - layer; j++) grid[layer][j] = elements[index++ % len];
for (let i = layer + 1; i < m - layer; i++) grid[i][n - layer - 1] = elements[index++ % len];
for (let j = n - layer - 2; j >= layer; j--) grid[m - layer - 1][j] = elements[index++ % len];
for (let i = m - layer - 2; i > layer; i--) grid[i][layer] = elements[index++ % len];
}
return grid;
}This Java implementation calculates the final position for each coordinate in a layer by tracing the layers and directly determining the new position using modular arithmetic. This avoids needing a separate layer list outside of the loop.
Time Complexity: O(m * n) since it visits each coordinate. Space Complexity: O(min(m, n)), for handling layer calculations in auxiliary arrays.
Approach 3: Default Approach
function rotateGrid(grid: number[][], k: number): number[][] {
const m = grid.length;
const n = grid[0].length;
const rotate = (p: number, k: number) => {
const nums: number[] = [];
for (let j = p; j < n - p - 1; ++j) {
nums.push(grid[p][j]);
}
for (let i = p; i < m - p - 1; ++i) {
nums.push(grid[i][n - p - 1]);
}
for (let j = n - p - 1; j > p; --j) {
nums.push(grid[m - p - 1][j]);
}
for (let i = m - p - 1; i > p; --i) {
nums.push(grid[i][p]);
}
const l = nums.length;
k %= l;
if (k === 0) {
return;
}
for (let j = p; j < n - p - 1; ++j) {
grid[p][j] = nums[k++ % l];
}
for (let i = p; i < m - p - 1; ++i) {
grid[i][n - p - 1] = nums[k++ % l];
}
for (let j = n - p - 1; j > p; --j) {
grid[m - p - 1][j] = nums[k++ % l];
}
for (let i = m - p - 1; i > p; --i) {
grid[i][p] = nums[k++ % l];
}
};
for (let p = 0; p < Math.min(m, n) >> 1; ++p) {
rotate(p, k);
}
return grid;
}func rotateGrid(grid [][]int, k int) [][]int {
m, n := len(grid), len(grid[0])
rotate := func(p, k int) {
nums := []int{}
for j := p; j < n-p-1; j++ {
nums = append(nums, grid[p][j])
}
for i := p; i < m-p-1; i++ {
nums = append(nums, grid[i][n-p-1])
}
for j := n - p - 1; j > p; j-- {
nums = append(nums, grid[m-p-1][j])
}
for i := m - p - 1; i > p; i-- {
nums = append(nums, grid[i][p])
}
l := len(nums)
k %= l
if k == 0 {
return
}
for j := p; j < n-p-1; j++ {
grid[p][j] = nums[k]
k = (k + 1) % l
}
for i := p; i < m-p-1; i++ {
grid[i][n-p-1] = nums[k]
k = (k + 1) % l
}
for j := n - p - 1; j > p; j-- {
grid[m-p-1][j] = nums[k]
k = (k + 1) % l
}
for i := m - p - 1; i > p; i-- {
grid[i][p] = nums[k]
k = (k + 1) % l
}
}
for i := 0; i < m/2 && i < n/2; i++ {
rotate(i, k)
}
return grid
}Complexity comparison
| Approach | Complexity |
|---|---|
| Layered Rotation Method | Time Complexity: O(m * n) as each element is visited once. Space Complexity: O(max(m, n)) due to the storage of one layer's elements. |
| Direct Coordinate Manipulation | Time Complexity: O(m * n) since it visits each coordinate. Space Complexity: O(min(m, n)), for handling layer calculations in auxiliary arrays. |
| Default Approach | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Layered Rotation Method | O(m*n) | O(min(m,n)) | Best for readability and interviews; easy to implement by extracting each matrix ring. |
| Direct Coordinate Manipulation | O(m*n) | O(1) | When minimizing extra memory or practicing index math for matrix simulation problems. |
Frequently asked questions
Is Cyclically Rotating a Grid easy or hard?
The problem is rated Medium because the core idea is simple but implementing layer boundaries and rotation correctly can be tricky. Handling perimeter length, rotation modulo, and edge traversal often causes off‑by‑one errors.
Cyclically Rotating a Grid Python/Java solution
Python and C++ implementations often use the layered rotation method with a temporary list for each ring. Java and JavaScript solutions can implement direct coordinate manipulation to compute the rotated position of every element without extra memory.
How to solve Cyclically Rotating a Grid in O(n)?
The optimal solution processes the matrix by layers and rotates each ring using k % perimeter_length. Since each element is moved only once during extraction and reinsertion, the total work across all layers is proportional to the number of cells, giving O(m*n) time.
What is the best approach for Cyclically Rotating a Grid?
The layered rotation method is the most practical approach. Treat each rectangular ring of the matrix as a circular array, compute the effective rotation using k % perimeter_length, rotate the elements, and write them back. This keeps the logic simple while running in O(m*n) time.
Is Cyclically Rotating a Grid asked at Google/Amazon/Meta?
Matrix rotation and layer traversal problems are common in interviews at companies like Amazon, Google, and Meta. Variants involving rotating rings, spiral traversal, or matrix simulations frequently appear in coding rounds and onsite interviews.
What data structure is used in Cyclically Rotating a Grid?
The solution primarily uses arrays and matrix traversal. In the layered approach, each ring of the matrix is temporarily stored in a list or array to perform cyclic rotation before writing values back into the grid.
What is the time complexity of Cyclically Rotating a Grid?
Both common solutions run in O(m*n) time because every element of the grid is processed at most a constant number of times. Layer extraction and coordinate‑based simulation both visit each cell once while handling rotations per layer.
