3643. Flip Square Submatrix Vertically

練習日期:2026-03-21

難度:Easy

類型:Array、Two Pointers、Matrix

📘 題目敘述

給你一個 m x n 的整數矩陣 grid,以及三個整數 xyk

其中:

  • xy 表示某個正方形子矩陣左上角的列與行 index
  • k 表示這個正方形子矩陣的邊長

你的任務是把這個子矩陣做垂直翻轉,也就是把它的列順序上下顛倒。

請回傳更新後的矩陣。

條件限制

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • 1 <= grid[i][j] <= 100
  • 0 <= x < m
  • 0 <= y < n
  • 1 <= k <= min(m - x, n - y)

🧠 解題思路

這題的重點是:

  • 只翻轉左上角在 (x, y)、大小為 k x k 的那塊正方形子矩陣
  • 而且翻轉方式是垂直翻轉
  • 也就是:第 1 列和最後 1 列交換、第 2 列和倒數第 2 列交換……

我這份寫法是先複製一份原本的矩陣到 ngrid,然後再把答案直接寫回 grid

這樣做的原因是:

如果直接在原本的 grid 上一邊改、一邊讀,可能前面改過的值會影響到後面還沒處理的格子。
所以我先保留一份原本狀態,之後所有要寫進去的新值,都從 ngrid 去讀。

對子矩陣中的每個位置 (x + i, y + j),它翻轉後應該對應到的原本位置是:

  • 列:(x + k - 1) - i
  • 行:y + j

也就是:

  • 上下列順序反過來
  • 但每一列中的左右位置不變

所以直接做:

  • grid[x + i][y + j] = ngrid[(x + k - 1) - i][y + j]

就可以完成這個垂直翻轉。

也就是說,這題的核心就是:

只在指定的 k x k 區塊內操作,並把每個位置的新值改成原本對稱列的位置值。

所有變數

  • ngrid:先複製出來的原矩陣,用來讀取翻轉前的值

🪜 主要流程步驟

1. 先複製一份原本的矩陣

vector<vector<int>> ngrid = grid;

這一步很重要。

因為後面要把翻轉後的結果直接寫回 grid
如果不先複製一份,那前面改過的值可能會影響到後面還要參考的原始內容。

所以這裡先用 ngrid 保存翻轉前的矩陣狀態。


2. 只枚舉指定的 k x k 子矩陣範圍

for (int i = 0; i < k; i++) {
    for (int j = 0; j < k; j++) {

這裡的 (i, j) 不是整個矩陣的座標,而是:

  • 相對於子矩陣左上角 (x, y) 的偏移量

所以:

  • x + i 是目前要改的實際列位置
  • y + j 是目前要改的實際行位置

這樣就只會處理題目指定的那塊正方形區域。


3. 把目前位置改成垂直翻轉後對應列的值

grid[x + i][y + j] = ngrid[(x + k - 1) - i][y + j];

這一行是整題最核心的地方。

原本子矩陣的列範圍是:

  • x
  • x + 1
  • ...
  • x + k - 1

做垂直翻轉後:

  • x 列要拿原本第 x + k - 1 列的值
  • x + 1 列要拿原本第 x + k - 2 列的值
  • ...
  • x + i 列要拿原本第 (x + k - 1) - i 列的值

而行不會改變,所以欄位仍然是:

  • y + j

因此這個對應公式剛好就是垂直翻轉。


4. 為什麼這樣是垂直翻轉,不是旋轉或水平翻轉

這份程式做的事情是:

  • 行號反過來
  • 但列中的欄位置不變

也就是:

  • 上下顛倒
  • 左右不動

所以它是垂直翻轉

如果是水平翻轉,應該會改的是欄號。
如果是旋轉,列號和欄號都會一起重新對應。
但這份程式只有列被反轉,所以完全符合題意。


5. 最後回傳更新後的 grid

return grid;

當指定子矩陣內的所有位置都改完後,grid 就已經是翻轉完成的矩陣,直接回傳即可。

⏱️ 複雜度

設子矩陣邊長為 k

  • 時間複雜度:O(k^2)
    只會掃過指定的 k x k 子矩陣一次。
  • 空間複雜度:O(mn)
    額外複製了一份整個矩陣 ngrid

💻 程式碼實作

class Solution {
public:
    vector<vector<int>> reverseSubmatrix(vector<vector<int>>& grid, int x,  int y, int k) { 
        vector<vector<int>> ngrid = grid;
        for (int i = 0; i < k; i++) {
            for (int j = 0; j < k; j++) {
                grid[x + i][y + j] = ngrid[(x + k - 1) - i][y + j];
            }
        }
        return grid;
    }
};

https://leetcode.com/problems/flip-square-submatrix-vertically/

作者: scottnick
撰寫日期: 2026-03-21
類別:
原文連結: https://scottnick.github.io/cpp-notes/all%20problems/3643-flip-square-submatrix-vertically.html