LeetCode 1260. 二维网格迁移
字数 2254 2025-12-06 09:54:41
LeetCode 1260. 二维网格迁移
题目描述
给你一个 m 行 n 列的二维网格 grid 和一个整数 k,你需要将 grid 迁移 k 次。
每次迁移操作如下:
- 位于
grid[i][j] 的元素将会移动到 grid[i][j+1]。
- 位于
grid[i][n-1] 的元素将会移动到 grid[i+1][0]。
- 位于
grid[m-1][n-1] 的元素将会移动到 grid[0][0]。
你需要返回进行 k 次迁移操作后最终得到的二维网格。
示例
输入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1
输出:[[9,1,2],[3,4,5],[6,7,8]]
解释:迁移 1 次后,末尾元素 9 移到开头,其余元素依次右移一位。
解题过程
第一步:理解迁移的实质
这是一个二维网格,但迁移规则本质上是将整个网格的所有元素按行优先顺序展开成一个一维数组,然后把这个数组循环右移 k 次,最后再按行优先顺序重新填充回 m × n 的网格。
以示例为例:
原始网格:
[1,2,3]
[4,5,6]
[7,8,9]
按行优先展开成一维数组:
[1,2,3,4,5,6,7,8,9]
循环右移 1 位后:
[9,1,2,3,4,5,6,7,8]
再按行优先重新填充成 3×3 网格:
[9,1,2]
[3,4,5]
[6,7,8]
与题目输出一致。
第二步:计算有效移动次数
如果直接移动 k 次,当 k 很大时效率很低。注意到:
- 如果网格有 m 行 n 列,总元素数 total = m × n。
- 循环右移 k 次 等价于 循环右移 k % total 次,因为每移动 total 次会回到初始状态。
所以先计算 k = k % (m*n),减少不必要的移动。
第三步:一维展开与映射
假设原始网格中位置 (i, j) 对应一维数组的索引是:
index = i * n + j
迁移 k 次后,这个元素的新一维索引是:
new_index = (index + k) % total
但注意,迁移规则是“向右移动”,在展开的一维数组中,对应的是循环右移,所以新位置应该是原索引加上 k(再取模)。
第四步:重建网格
得到新的一维索引后,我们需要将它映射回二维坐标:
新行号:new_i = new_index // n
新列号:new_j = new_index % n
然后新建一个 m×n 的结果网格 ans,将原 grid[i][j] 的值放到 ans[new_i][new_j] 中。
第五步:逐步示例
以示例 grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1 为例:
- m=3, n=3, total=9, k=1%9=1。
- 遍历原网格每个位置 (i,j):
- (0,0): index=0, new_index=(0+1)%9=1, new_i=1//3=0, new_j=1%3=1 → ans[0][1]=1
- (0,1): index=1, new_index=2, new_i=0, new_j=2 → ans[0][2]=2
- (0,2): index=2, new_index=3, new_i=1, new_j=0 → ans[1][0]=3
- (1,0): index=3, new_index=4, new_i=1, new_j=1 → ans[1][1]=4
- (1,1): index=4, new_index=5, new_i=1, new_j=2 → ans[1][2]=5
- (1,2): index=5, new_index=6, new_i=2, new_j=0 → ans[2][0]=6
- (2,0): index=6, new_index=7, new_i=2, new_j=1 → ans[2][1]=7
- (2,1): index=7, new_index=8, new_i=2, new_j=2 → ans[2][2]=8
- (2,2): index=8, new_index=0, new_i=0, new_j=0 → ans[0][0]=9
- 得到的 ans 正是输出。
第六步:实现要点
- 边界情况:若 k=0 或 total=1,直接返回原网格。
- 注意迁移方向:题目是“向右移动”,对应一维数组的循环右移。
- 时间复杂度 O(m×n),空间复杂度 O(m×n)(用于结果网格)。
第七步:直接计算法(优化)
也可以不通过中间一维数组,直接计算每个新位置的值:
对于结果网格的每个位置 (i, j),它对应的原始元素的一维索引是:
original_index = (i * n + j - k + total) % total
然后从 original_index 得到原坐标:
original_i = original_index // n
original_j = original_index % n
这样可以直接赋值 ans[i][j] = grid[original_i][original_j]。
LeetCode 1260. 二维网格迁移 题目描述 给你一个 m 行 n 列的二维网格 grid 和一个整数 k ,你需要将 grid 迁移 k 次。 每次迁移操作如下: 位于 grid[i][j] 的元素将会移动到 grid[i][j+1] 。 位于 grid[i][n-1] 的元素将会移动到 grid[i+1][0] 。 位于 grid[m-1][n-1] 的元素将会移动到 grid[0][0] 。 你需要返回进行 k 次迁移操作后最终得到的二维网格。 示例 输入:grid = [ [ 1,2,3],[ 4,5,6],[ 7,8,9] ], k = 1 输出:[ [ 9,1,2],[ 3,4,5],[ 6,7,8] ] 解释:迁移 1 次后,末尾元素 9 移到开头,其余元素依次右移一位。 解题过程 第一步:理解迁移的实质 这是一个二维网格,但迁移规则本质上是将整个网格的所有元素按 行优先顺序 展开成一个一维数组,然后把这个数组 循环右移 k 次,最后再按行优先顺序重新填充回 m × n 的网格。 以示例为例: 原始网格: [ 1,2,3 ] [ 4,5,6 ] [ 7,8,9 ] 按行优先展开成一维数组: [ 1,2,3,4,5,6,7,8,9 ] 循环右移 1 位后: [ 9,1,2,3,4,5,6,7,8 ] 再按行优先重新填充成 3×3 网格: [ 9,1,2 ] [ 3,4,5 ] [ 6,7,8 ] 与题目输出一致。 第二步:计算有效移动次数 如果直接移动 k 次,当 k 很大时效率很低。注意到: 如果网格有 m 行 n 列,总元素数 total = m × n。 循环右移 k 次 等价于 循环右移 k % total 次,因为每移动 total 次会回到初始状态。 所以先计算 k = k % (m*n) ,减少不必要的移动。 第三步:一维展开与映射 假设原始网格中位置 (i, j) 对应一维数组的索引是: index = i * n + j 迁移 k 次后,这个元素的新一维索引是: new_index = (index + k) % total 但注意,迁移规则是“向右移动”,在展开的一维数组中,对应的是 循环右移 ,所以新位置应该是原索引加上 k(再取模)。 第四步:重建网格 得到新的一维索引后,我们需要将它映射回二维坐标: 新行号: new_i = new_index // n 新列号: new_j = new_index % n 然后新建一个 m×n 的结果网格 ans ,将原 grid[i][j] 的值放到 ans[new_i][new_j] 中。 第五步:逐步示例 以示例 grid = [ [ 1,2,3],[ 4,5,6],[ 7,8,9] ], k = 1 为例: m=3, n=3, total=9, k=1%9=1。 遍历原网格每个位置 (i,j): (0,0): index=0, new_ index=(0+1)%9=1, new_ i=1//3=0, new_ j=1%3=1 → ans[ 0][ 1 ]=1 (0,1): index=1, new_ index=2, new_ i=0, new_ j=2 → ans[ 0][ 2 ]=2 (0,2): index=2, new_ index=3, new_ i=1, new_ j=0 → ans[ 1][ 0 ]=3 (1,0): index=3, new_ index=4, new_ i=1, new_ j=1 → ans[ 1][ 1 ]=4 (1,1): index=4, new_ index=5, new_ i=1, new_ j=2 → ans[ 1][ 2 ]=5 (1,2): index=5, new_ index=6, new_ i=2, new_ j=0 → ans[ 2][ 0 ]=6 (2,0): index=6, new_ index=7, new_ i=2, new_ j=1 → ans[ 2][ 1 ]=7 (2,1): index=7, new_ index=8, new_ i=2, new_ j=2 → ans[ 2][ 2 ]=8 (2,2): index=8, new_ index=0, new_ i=0, new_ j=0 → ans[ 0][ 0 ]=9 得到的 ans 正是输出。 第六步:实现要点 边界情况:若 k=0 或 total=1,直接返回原网格。 注意迁移方向:题目是“向右移动”,对应一维数组的循环右移。 时间复杂度 O(m×n),空间复杂度 O(m×n)(用于结果网格)。 第七步:直接计算法(优化) 也可以不通过中间一维数组,直接计算每个新位置的值: 对于结果网格的每个位置 (i, j),它对应的原始元素的一维索引是: original_index = (i * n + j - k + total) % total 然后从 original_ index 得到原坐标: original_i = original_index // n original_j = original_index % n 这样可以直接赋值 ans[i][j] = grid[original_i][original_j] 。