Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions problems/1260-shift-2d-grid/analysis.md
Original file line number Diff line number Diff line change
@@ -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`.
69 changes: 69 additions & 0 deletions problems/1260-shift-2d-grid/problem.md
Original file line number Diff line number Diff line change
@@ -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`
40 changes: 40 additions & 0 deletions problems/1260-shift-2d-grid/solution_daily_20260720.go
Original file line number Diff line number Diff line change
@@ -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
}
79 changes: 79 additions & 0 deletions problems/1260-shift-2d-grid/solution_daily_20260720_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}