class Solution:
def rotateGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
m, n = len(grid), len(grid[0])
layers = min(m, n) // 2
res = [row[:] for row in grid]
for layer in range(layers):
elements = []
# Top row
for j in range(layer, n-layer):
elements.append(grid[layer][j])
# Right column
for i in range(layer+1, m-layer-1):
elements.append(grid[i][n-layer-1])
# Bottom row
for j in range(n-layer-1, layer-1, -1):
elements.append(grid[m-layer-1][j])
# Left column
for i in range(m-layer-2, layer, -1):
elements.append(grid[i][layer])
total = len(elements)
k_mod = k % total
rotated = elements[k_mod:] + elements[:k_mod]
idx = 0
# Place back rotated elements
for j in range(layer, n-layer):
res[layer][j] = rotated[idx]
idx += 1
for i in range(layer+1, m-layer-1):
res[i][n-layer-1] = rotated[idx]
idx += 1
for j in range(n-layer-1, layer-1, -1):
res[m-layer-1][j] = rotated[idx]
idx += 1
for i in range(m-layer-2, layer, -1):
res[i][layer] = rotated[idx]
idx += 1
return res
class Solution {
public:
vector<vector<int>> rotateGrid(vector<vector<int>>& grid, int k) {
int m = grid.size(), n = grid[0].size();
int layers = min(m, n) / 2;
vector<vector<int>> res = grid;
for (int layer = 0; layer < layers; ++layer) {
vector<int> elements;
// Top row
for (int j = layer; j < n-layer; ++j)
elements.push_back(grid[layer][j]);
// Right column
for (int i = layer+1; i < m-layer-1; ++i)
elements.push_back(grid[i][n-layer-1]);
// Bottom row
for (int j = n-layer-1; j >= layer; --j)
elements.push_back(grid[m-layer-1][j]);
// Left column
for (int i = m-layer-2; i > layer; --i)
elements.push_back(grid[i][layer]);
int total = elements.size();
int k_mod = k % total;
vector<int> rotated(total);
for (int i = 0; i < total; ++i)
rotated[i] = elements[(i + k_mod) % total];
int idx = 0;
// Place back rotated elements
for (int j = layer; j < n-layer; ++j)
res[layer][j] = rotated[idx++];
for (int i = layer+1; i < m-layer-1; ++i)
res[i][n-layer-1] = rotated[idx++];
for (int j = n-layer-1; j >= layer; --j)
res[m-layer-1][j] = rotated[idx++];
for (int i = m-layer-2; i > layer; --i)
res[i][layer] = rotated[idx++];
}
return res;
}
};
class Solution {
public int[][] rotateGrid(int[][] grid, int k) {
int m = grid.length, n = grid[0].length;
int layers = Math.min(m, n) / 2;
int[][] res = new int[m][n];
for (int i = 0; i < m; i++)
res[i] = grid[i].clone();
for (int layer = 0; layer < layers; layer++) {
List<Integer> elements = new ArrayList<>();
// Top row
for (int j = layer; j < n-layer; j++)
elements.add(grid[layer][j]);
// Right column
for (int i = layer+1; i < m-layer-1; i++)
elements.add(grid[i][n-layer-1]);
// Bottom row
for (int j = n-layer-1; j >= layer; j--)
elements.add(grid[m-layer-1][j]);
// Left column
for (int i = m-layer-2; i > layer; i--)
elements.add(grid[i][layer]);
int total = elements.size();
int k_mod = k % total;
List<Integer> rotated = new ArrayList<>();
for (int i = 0; i < total; i++)
rotated.add(elements.get((i + k_mod) % total));
int idx = 0;
// Place back rotated elements
for (int j = layer; j < n-layer; j++)
res[layer][j] = rotated.get(idx++);
for (int i = layer+1; i < m-layer-1; i++)
res[i][n-layer-1] = rotated.get(idx++);
for (int j = n-layer-1; j >= layer; j--)
res[m-layer-1][j] = rotated.get(idx++);
for (int i = m-layer-2; i > layer; i--)
res[i][layer] = rotated.get(idx++);
}
return res;
}
}
var rotateGrid = function(grid, k) {
const m = grid.length, n = grid[0].length;
const layers = Math.floor(Math.min(m, n) / 2);
const res = grid.map(row => row.slice());
for (let layer = 0; layer < layers; layer++) {
let elements = [];
// Top row
for (let j = layer; j < n-layer; j++)
elements.push(grid[layer][j]);
// Right column
for (let i = layer+1; i < m-layer-1; i++)
elements.push(grid[i][n-layer-1]);
// Bottom row
for (let j = n-layer-1; j >= layer; j--)
elements.push(grid[m-layer-1][j]);
// Left column
for (let i = m-layer-2; i > layer; i--)
elements.push(grid[i][layer]);
const total = elements.length;
const k_mod = k % total;
const rotated = elements.slice(k_mod).concat(elements.slice(0, k_mod));
let idx = 0;
// Place back rotated elements
for (let j = layer; j < n-layer; j++)
res[layer][j] = rotated[idx++];
for (let i = layer+1; i < m-layer-1; i++)
res[i][n-layer-1] = rotated[idx++];
for (let j = n-layer-1; j >= layer; j--)
res[m-layer-1][j] = rotated[idx++];
for (let i = m-layer-2; i > layer; i--)
res[i][layer] = rotated[idx++];
}
return res;
};
You are given a 2D integer grid called grid
and an integer k
. The task is to cyclically rotate each "layer" of the grid in a clockwise direction, k
times. A layer is defined as a set of elements that form a border around the grid or its subgrids (like the outermost border, then the next inner border, etc.).
For each rotation, every element in a layer moves one position forward along the border of the layer. After rotating all layers k
times, you must return the modified grid.
Constraints:
To solve this problem, first, we need to understand what a "layer" is. Imagine peeling an onion: the outermost layer is the border, and as you move inward, you encounter more layers. For each layer, we need to collect its elements, rotate them, and then put them back in their respective places.
A brute-force approach would be to rotate the entire grid k
times, moving each element one by one, but this is inefficient, especially for large k
. Instead, we can optimize by:
The solution involves processing each layer independently. Here is a step-by-step breakdown:
min(m, n) // 2
, where m
and n
are the grid's dimensions.
k % len(layer)
to avoid unnecessary full cycles.k % len(layer)
.This approach ensures each element is moved exactly once per rotation, and the use of lists and modular arithmetic makes the process efficient.
Suppose grid = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
and k = 2
.
Layer 0 (outermost):
Layer 1 (inner):
Resulting grid:
This step-by-step process demonstrates how each layer is rotated independently and efficiently.
Brute-force Approach:
k
times.
The optimized approach is much faster for large k
values, as it avoids unnecessary rotations by using modular arithmetic.
The key to solving the cyclically rotating grid problem efficiently is to process each layer independently, extract its elements, rotate them using modular arithmetic, and place them back. This avoids redundant moves and leverages the structure of the grid, resulting in a clean and efficient solution that scales well for large grids and large k
. The approach is both intuitive and optimal, making it a great example of algorithmic thinking.