置頂

GeoGebra 文章目錄

GeoGebra 文章目錄  更新日期:2018/2/8 我將 GeoGebra 相關的文章及檔案連結都整理在這篇裡,之後如果有新的文章也會同時更新這個目錄。上傳到 GeoGebraTube 的檔案,我有試著用 Google Chrome 63.0.3239.13...

熱門文章

2026年7月20日 星期一

LeetCode 解題筆記:1260. Shift 2D Grid

作者:王一哲
日期:2026年7月20日


LeetCode 題目連結:1260. Shift 2D Grid

解題想法


簡單題。題目給一個大小為 $m \times n$ 的二維陣列 $grid$,依照以下的 3 個規則操作 $k$ 次,回傳操作後的陣列。
  1. 將 $grid[i][j]$ 移到 $grid[i][j+1]$
  2. 將 $grid[i][n-1]$ 移到 $grid[i+1][0]$
  3. 將 $grid[m-1][n-1]$ 移到 $grid[0][0]$
由於這題的操作次數 $k$ 最多為 $100$ 次,可以直接模擬移動過程,不過這樣寫速度會比較慢。

我們可以觀察範例
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;
    }
};


沒有留言:

張貼留言