DDSA Solutions

1914. Cyclically Rotating a Grid

Time: O(m*n + k*layers)
Space: O(1)
Advertisement

Intuition

A grid has concentric rectangular layers like an onion. Rotating layer by layer independently is easier than rotating the whole grid at once. Each layer is a linear sequence (top → right → bottom → left), so rotating k is just a cyclic shift of that sequence. Modulo by layer size eliminates redundant full rotations.

Algorithm

  1. 1Initialise pointers: t (top), l (left), b (bottom), r (right) bounding the current layer.
  2. 2While t < b and l < r (more than one layer remains):
  3. 3 1) Compute the ring size: 2*(b-t) + 2*(r-l).
  4. 4 2) Compute net rotations: k % ringSize.
  5. 5 3) For each rotation, shift elements one position clockwise around the ring.
  6. 6 4) Move inward: t++, l++, b--, r--.

Example Walkthrough

Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1

  1. 1.Layer 1 (ring): [1,2,3,6,9,8,7,4].
  2. 2.Rotate 1 step: [4,1,2,3,6,9,8,7].
  3. 3.Place back: grid[0]=[4,1,2], grid[1]=[7,5,3], grid[2]=[8,9,6].

Output: [[4,1,2],[7,5,3],[8,9,6]]

Common Pitfalls

  • Modulo ring size avoids simulating every single rotation; k=5 on a 4-element ring is just k=1.
  • After each rotation iteration, all four directions (top, right, bottom, left) must shift elements; forgetting one causes the ring to corrupt.
  • When t == b or l == r, the layer is a single row or column and requires special handling or the loop condition prevents it.
1914.cs
C#
// Approach: Process concentric layers from outside inward; for each layer, extract the ring of elements,
// rotate the ring by k % ringSize positions, and place them back.
// The ring is linearized: top row (left to right) → right column (top to bottom) → bottom row (right to left) → left column (bottom to top).
// Use modulo to avoid full rotations when k exceeds layer length.
// Time: O(m*n + k*layers) Space: O(1) excluding output

public class Solution
{
    public int[][] RotateGrid(int[][] grid, int k)
    {
        int m = grid.Length;
        int n = grid[0].Length;
        int t = 0;     // the top
        int l = 0;     // the left
        int b = m - 1; // the bottom
        int r = n - 1; // the right

        while (t < b && l < r)
        {
            int elementInThisLayer = 2 * (b - t + 1) + 2 * (r - l + 1) - 4;
            int netRotations = k % elementInThisLayer;
            for (int rotate = 0; rotate < netRotations; ++rotate)
            {
                int topLeft = grid[t][l];
                for (int j = l; j < r; ++j)
                    grid[t][j] = grid[t][j + 1];
                for (int i = t; i < b; ++i)
                    grid[i][r] = grid[i + 1][r];
                for (int j = r; j > l; --j)
                    grid[b][j] = grid[b][j - 1];
                for (int i = b; i > t; --i)
                    grid[i][l] = grid[i - 1][l];
                grid[t + 1][l] = topLeft;
            }
            ++t;
            ++l;
            --b;
            --r;
        }

        return grid;
    }
}
Advertisement
Was this solution helpful?