日期:2026年7月20日
LeetCode 題目連結:1260. Shift 2D Grid
解題想法
簡單題。題目給一個大小為 $m \times n$ 的二維陣列 $grid$,依照以下的 3 個規則操作 $k$ 次,回傳操作後的陣列。
- 將 $grid[i][j]$ 移到 $grid[i][j+1]$
- 將 $grid[i][n-1]$ 移到 $grid[i+1][0]$
- 將 $grid[m-1][n-1]$ 移到 $grid[0][0]$
我們可以觀察範例
grid = [[1,2,3],[4,5,6],[7,8,9]]
操作 1 次之後變成
[[9,1,2],[3,4,5],[6,7,8]]
如果將原來的二維陣列頭尾相接成一維陣列,以上的操作就是所有元素向後平移一格,最後一格移到最前面。利用這個性質,我們可以先將操作次數 $k$ 對 $m \times n$ 取餘數,因為每操作 $m \times n$ 次陣列會恢愎原狀。用兩層 for 迴圈掃過陣列,外層 $i = 0$ 到 $i = m-1$,內層 $j = 0$ 到 $j = n-1$,對應到平移後的一維陣列索引值 $pos = i \times n + j + k \pmod {m \times n}$,再換回二維陣列的索引值 $[pos / n, pos \pmod n]$。
Python 程式碼
直接模擬操作過程。Runtime: 151 ms, beats 12.14%. Memory: 19.66 MB, beats 48.15%.
class Solution:
def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
m, n = len(grid), len(grid[0])
mat = [[0] * n for _ in range(m)]
for _ in range(k):
for i in range(m):
for j in range(n):
mat[i][(j + 1) % n] = grid[i][j]
last = mat[m-1][0]
for i in range(m-1, 0, -1):
mat[i][0] = mat[i-1][0]
mat[0][0] = last
grid, mat = mat, grid
return grid
當作一維串列計算平移後的索引值。Runtime: 3 ms, beats 83.13%. Memory: 19.40 MB, beats 48.15%.
class Solution:
def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
# 當成1維串列計算索引值,向右平移 k 格,再轉回2維串列
m, n = len(grid), len(grid[0])
tot = m * n
k %= tot
ans = [[0] * n for _ in range(m)] # 儲存答案用的2維串列
for i in range(m):
for j in range(n):
pos = (i * n + j + k) % tot
ans[pos // n][pos % n] = grid[i][j]
return ans
攤平成一維串列,用切片平移串列,再填回二維串列之中。Runtime: 3 ms, beats 83.13%. Memory: 19.75 MB, beats 19.55%.
class Solution:
def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
# 拉平成1維串列,向右平移 k 格,再轉回2維串列
m, n = len(grid), len(grid[0])
k %= m * n
arr = [val for row in grid for val in row]
arr = arr[m*n - k:] + arr[:m*n - k]
for i in range(m):
grid[i] = arr[i*n : (i+1)*n]
print(arr)
return grid
C++ 程式碼
直接模擬操作過程。Runtime: 11 ms, beats 12.43%. Memory: 18.88 MB, beats 20.65%.
class Solution {
public:
vector<vector<int>> shiftGrid(vector<vector<int>>& grid, int k) {
// 完整模擬移動過程,速度很慢
int m = (int)grid.size(), n = (int)grid[0].size();
vector<vector<int>> mat (m, vector<int> (n, 0));
for(int t = 0; t < k; t++) {
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
mat[i][(j + 1) % n] = grid[i][j];
}
}
int last = mat[m-1][0];
for(int i = m-1; i > 0; i--) {
mat[i][0] = mat[i-1][0];
}
mat[0][0] = last;
swap(grid, mat);
}
return grid;
}
};
當作一維陣列計算平移後的索引值。Runtime: 0 ms, beats 100.00%. Memory: 18.22 MB, beats 39.33%.
class Solution {
public:
vector<vector<int>> shiftGrid(vector<vector<int>>& grid, int k) {
// 當成1維陣列計算索引值,向右平移 k 格,再轉回2維陣列
int m = (int)grid.size(), n = (int)grid[0].size();
int tot = m * n; // 元素數量
k %= tot; // 平移格數
vector<vector<int>> ans (m, vector<int> (n, 0)); // 儲存答案用的2維陣列
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
int pos = (i * n + j + k) % tot; // 轉成1維陣列的索引值
ans[pos / n][pos % n] = grid[i][j]; // 換算成2維陣列的索引值
}
}
return ans;
}
};
沒有留言:
張貼留言