diff --git a/problems/1260-shift-2d-grid/analysis.md b/problems/1260-shift-2d-grid/analysis.md new file mode 100644 index 0000000..a966c73 --- /dev/null +++ b/problems/1260-shift-2d-grid/analysis.md @@ -0,0 +1,55 @@ +# 1260. Shift 2D Grid + +[LeetCode Link](https://leetcode.com/problems/shift-2d-grid/) + +Difficulty: Easy +Topics: Array, Matrix, Simulation +Acceptance Rate: 69.3% + +## Hints + +### Hint 1 + +Shifting each element one cell to the right, wrapping from the end of a row to the start of the next, and from the last cell of the grid back to the very first, is just a rotation. Ask yourself: what one-dimensional structure does a 2D grid become if you "unroll" it row by row? + +### Hint 2 + +Instead of literally performing `k` separate shift passes (which is wasteful), think of the grid as a flat list of `m * n` numbers laid out in reading order. A single shift moves every value one position forward in that flat list, and the last value wraps around to the front. That means the whole operation is a **cyclic shift of a 1D array by `k`**. + +### Hint 3 + +The key insight is index arithmetic. An element at row `i`, column `j` sits at flat index `i * n + j`. After shifting `k` times, its new flat index is `(i * n + j + k) mod (m * n)`. Convert that new flat index back to 2D coordinates with `row = idx / n` and `col = idx % n`. Because shifting by `m * n` returns the grid to its original state, reduce `k` with `k mod (m * n)` first — this also explains Example 3, where `k = 9` on a 9-cell grid changes nothing. + +## Approach + +Treat the grid as a one-dimensional sequence read left-to-right, top-to-bottom. There are `total = m * n` cells. One shift advances every element by exactly one position in this flattened order, with wrap-around. Therefore `k` shifts advance every element by `k` positions modulo `total`. + +Algorithm: + +1. Read the grid dimensions `m` (rows) and `n` (columns) and compute `total = m * n`. +2. Allocate a fresh result grid of the same shape so we never overwrite values we still need to read. +3. For each cell `(i, j)`: + - Its flat index is `flat = i*n + j`. + - Its destination flat index is `dest = (flat + k) % total`. + - Write the value into `result[dest/n][dest%n]`. +4. Return `result`. + +Reducing `k` by `k % total` is optional for correctness here because we already take the modulo when computing `dest`, but it keeps the arithmetic small and makes the "full rotation is a no-op" property explicit. + +Walking through Example 1 with `grid = [[1,2,3],[4,5,6],[7,8,9]]`, `k = 1`, `n = 3`, `total = 9`: value `9` is at `(2,2)`, flat index `8`; its destination is `(8+1) % 9 = 0`, i.e. `(0,0)`. Value `1` at flat `0` goes to flat `1`, i.e. `(0,1)`. Doing this for every cell produces `[[9,1,2],[3,4,5],[6,7,8]]`, matching the expected output. + +Using a separate output grid avoids the classic in-place hazard of clobbering a cell before it has been moved, and computing destinations directly avoids simulating `k` full passes. + +## Complexity Analysis + +Time Complexity: O(m * n) — every cell is read once and written once, independent of `k`. +Space Complexity: O(m * n) — for the newly built result grid (O(1) extra beyond the required output). + +## Edge Cases + +- **k is 0:** No shift should occur; the modulo arithmetic yields `dest = flat`, returning an identical grid. +- **k is a multiple of m * n (e.g. Example 3):** A full number of rotations returns the grid to its original state. `(flat + k) % total == flat`, so the output equals the input. +- **k larger than m * n:** Naively looping `k` times wastes work; the modulo reduces `k` into the meaningful range `[0, total)`. +- **Single row (m == 1):** Degrades to a plain cyclic shift of one array; the same index math handles it. +- **Single column (n == 1):** Every shift moves a value down one row and wraps the bottom to the top; `dest/n` and `dest%n` still resolve correctly since `n == 1`. +- **1x1 grid:** `total == 1`, so every destination is `(flat + k) % 1 == 0`; the single element stays put for any `k`. diff --git a/problems/1260-shift-2d-grid/problem.md b/problems/1260-shift-2d-grid/problem.md new file mode 100644 index 0000000..1bfef26 --- /dev/null +++ b/problems/1260-shift-2d-grid/problem.md @@ -0,0 +1,69 @@ +--- +number: "1260" +frontend_id: "1260" +title: "Shift 2D Grid" +slug: "shift-2d-grid" +difficulty: "Easy" +topics: + - "Array" + - "Matrix" + - "Simulation" +acceptance_rate: 6925.9 +is_premium: false +created_at: "2026-07-20T04:12:12.493169+00:00" +fetched_at: "2026-07-20T04:12:12.493169+00:00" +link: "https://leetcode.com/problems/shift-2d-grid/" +date: "2026-07-20" +--- + +# 1260. Shift 2D Grid + +Given a 2D `grid` of size `m x n` and an integer `k`. You need to shift the `grid` `k` times. + +In one shift operation: + + * Element at `grid[i][j]` moves to `grid[i][j + 1]`. + * Element at `grid[i][n - 1]` moves to `grid[i + 1][0]`. + * Element at `grid[m - 1][n - 1]` moves to `grid[0][0]`. + + + +Return the _2D grid_ after applying shift operation `k` times. + + + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2019/11/05/e1.png) + + + **Input:** grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1 + **Output:** [[9,1,2],[3,4,5],[6,7,8]] + + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2019/11/05/e2.png) + + + **Input:** grid = [[3,8,1,9],[19,7,2,5],[4,6,11,10],[12,0,21,13]], k = 4 + **Output:** [[12,0,21,13],[3,8,1,9],[19,7,2,5],[4,6,11,10]] + + +**Example 3:** + + + **Input:** grid = [[1,2,3],[4,5,6],[7,8,9]], k = 9 + **Output:** [[1,2,3],[4,5,6],[7,8,9]] + + + + +**Constraints:** + + * `m == grid.length` + * `n == grid[i].length` + * `1 <= m <= 50` + * `1 <= n <= 50` + * `-1000 <= grid[i][j] <= 1000` + * `0 <= k <= 100` diff --git a/problems/1260-shift-2d-grid/solution_daily_20260720.go b/problems/1260-shift-2d-grid/solution_daily_20260720.go new file mode 100644 index 0000000..4fece22 --- /dev/null +++ b/problems/1260-shift-2d-grid/solution_daily_20260720.go @@ -0,0 +1,40 @@ +package main + +// Shift 2D Grid (LeetCode 1260) +// +// A single shift moves every element one position forward when the grid is +// read row by row, with the last cell wrapping to the first. Flattening the +// grid into m*n cells turns k shifts into a cyclic shift by k. An element at +// (i, j) has flat index i*n+j; after k shifts its destination flat index is +// (i*n + j + k) % (m*n), which we convert back to (row, col) via /n and %n. +// A fresh result grid avoids overwriting cells we still need to read. +// +// Time: O(m*n) — each cell read and written once, independent of k. +// Space: O(m*n) — the returned result grid. +func shiftGrid(grid [][]int, k int) [][]int { + m := len(grid) + if m == 0 { + return grid + } + n := len(grid[0]) + if n == 0 { + return grid + } + + total := m * n + k %= total + + result := make([][]int, m) + for i := range result { + result[i] = make([]int, n) + } + + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + dest := (i*n + j + k) % total + result[dest/n][dest%n] = grid[i][j] + } + } + + return result +} diff --git a/problems/1260-shift-2d-grid/solution_daily_20260720_test.go b/problems/1260-shift-2d-grid/solution_daily_20260720_test.go new file mode 100644 index 0000000..639b17b --- /dev/null +++ b/problems/1260-shift-2d-grid/solution_daily_20260720_test.go @@ -0,0 +1,79 @@ +package main + +import ( + "reflect" + "testing" +) + +func TestShiftGrid(t *testing.T) { + tests := []struct { + name string + grid [][]int + k int + expected [][]int + }{ + { + name: "example 1: shift 3x3 by 1", + grid: [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + k: 1, + expected: [][]int{{9, 1, 2}, {3, 4, 5}, {6, 7, 8}}, + }, + { + name: "example 2: shift 4x4 by 4", + grid: [][]int{{3, 8, 1, 9}, {19, 7, 2, 5}, {4, 6, 11, 10}, {12, 0, 21, 13}}, + k: 4, + expected: [][]int{{12, 0, 21, 13}, {3, 8, 1, 9}, {19, 7, 2, 5}, {4, 6, 11, 10}}, + }, + { + name: "example 3: full rotation is a no-op (k equals m*n)", + grid: [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + k: 9, + expected: [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + }, + { + name: "edge case: k is 0 leaves grid unchanged", + grid: [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + k: 0, + expected: [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + }, + { + name: "edge case: k larger than m*n reduces via modulo", + grid: [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + k: 10, + expected: [][]int{{9, 1, 2}, {3, 4, 5}, {6, 7, 8}}, + }, + { + name: "edge case: single row behaves like 1D cyclic shift", + grid: [][]int{{1, 2, 3, 4}}, + k: 2, + expected: [][]int{{3, 4, 1, 2}}, + }, + { + name: "edge case: single column wraps bottom to top", + grid: [][]int{{1}, {2}, {3}}, + k: 1, + expected: [][]int{{3}, {1}, {2}}, + }, + { + name: "edge case: 1x1 grid stays put for any k", + grid: [][]int{{7}}, + k: 100, + expected: [][]int{{7}}, + }, + { + name: "edge case: negative values are preserved", + grid: [][]int{{-1, -2}, {-3, -4}}, + k: 1, + expected: [][]int{{-4, -1}, {-2, -3}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := shiftGrid(tt.grid, tt.k) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("shiftGrid(%v, %d) = %v, want %v", tt.grid, tt.k, result, tt.expected) + } + }) + } +}