3643. Flip Square Submatrix Vertically
Problem Description
You are given a 2D integer matrix grid
with dimensions m x n
, along with three integers x
, y
, and k
.
The parameters represent:
x
andy
: The row and column indices of the top-left corner of a square submatrix withingrid
k
: The size (side length) of the square submatrix
Your task is to flip the square submatrix vertically by reversing the order of its rows. This means:
- The first row of the submatrix becomes the last row
- The second row becomes the second-to-last row
- And so on, until all rows in the submatrix are reversed
For example, if you have a 3Γ3 submatrix:
1 2 3 4 5 6 7 8 9
After flipping vertically, it becomes:
7 8 9 4 5 6 1 2 3
The operation only affects the k Γ k
submatrix starting at position (x, y)
. All other elements in the grid remain unchanged.
Return the modified matrix after performing the vertical flip operation on the specified submatrix.
Intuition
To flip a submatrix vertically, we need to reverse the order of its rows. Think of it like flipping a stack of cards - the top card goes to the bottom, the bottom card goes to the top, and the middle cards swap positions accordingly.
The key insight is that we don't need to process all k
rows. We only need to swap pairs of rows that are equidistant from the center. The first row swaps with the last row, the second row swaps with the second-to-last row, and so on. This means we only need to iterate through half of the rows: k // 2
.
For each row i
that we process (starting from row x
), we need to find its corresponding row to swap with. If i
is the current row index, then its distance from the starting row x
is (i - x)
. The corresponding row from the bottom would be at distance (i - x)
from the last row of the submatrix. Since the last row of the submatrix is at index x + k - 1
, the corresponding row index i2
can be calculated as: i2 = x + k - 1 - (i - x)
.
Once we identify the two rows to swap, we need to exchange all elements in those rows within the submatrix bounds. This means swapping elements from column y
to column y + k - 1
between rows i
and i2
.
The beauty of this approach is that it modifies the matrix in-place without requiring extra space for a temporary matrix. By swapping rows pairwise, we achieve the vertical flip efficiently in O(kΒ²)
time, where we visit each element in the submatrix exactly once.
Learn more about Two Pointers patterns.
Solution Approach
The implementation follows a straightforward simulation approach to flip the submatrix vertically by swapping rows.
Step 1: Determine the rows to swap
We iterate from row x
to row x + k // 2 - 1
. This gives us exactly βk/2β
rows to process. We use integer division k // 2
because:
- If
k
is even (e.g., 4), we swap 2 pairs of rows - If
k
is odd (e.g., 5), we swap 2 pairs of rows, and the middle row stays in place
Step 2: Calculate the corresponding row index
For each row i
in the range [x, x + k // 2)
, we calculate its mirror row i2
:
i2 = x + k - 1 - (i - x)
This formula works because:
(i - x)
gives us the offset of rowi
from the start of the submatrixx + k - 1
is the index of the last row in the submatrix- Subtracting the offset from the last row index gives us the corresponding row from the bottom
Step 3: Swap elements between the two rows
For each column j
in the range [y, y + k)
, we swap the elements at positions grid[i][j]
and grid[i2][j]
:
grid[i][j], grid[i2][j] = grid[i2][j], grid[i][j]
This Python syntax performs the swap in a single line without needing a temporary variable.
Step 4: Return the modified matrix
After all swaps are complete, we return the modified grid
. Since we're modifying the matrix in-place, the original matrix is directly updated.
Time Complexity: O(kΒ²)
- We visit each element in the k Γ k
submatrix exactly once.
Space Complexity: O(1)
- We only use a constant amount of extra space for loop variables and temporary swapping.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to illustrate the solution approach.
Given:
- A 4Γ4 grid:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- Parameters:
x = 1
,y = 1
,k = 3
This means we need to flip a 3Γ3 submatrix starting at position (1,1).
Step 1: Identify the submatrix The 3Γ3 submatrix starting at (1,1) contains:
6 7 8 10 11 12 14 15 16
Step 2: Determine rows to swap
Since k = 3
, we need to process k // 2 = 3 // 2 = 1
row pair.
- We'll iterate with
i
fromx = 1
tox + k//2 - 1 = 1 + 1 - 1 = 1
- So we only process row
i = 1
Step 3: Calculate mirror row
For i = 1
:
- Calculate
i2 = x + k - 1 - (i - x)
i2 = 1 + 3 - 1 - (1 - 1) = 3
- So row 1 will swap with row 3
Step 4: Swap elements
For columns j
from y = 1
to y + k - 1 = 3
:
- When
j = 1
: Swapgrid[1][1]
(6) withgrid[3][1]
(14) - When
j = 2
: Swapgrid[1][2]
(7) withgrid[3][2]
(15) - When
j = 3
: Swapgrid[1][3]
(8) withgrid[3][3]
(16)
After swapping row 1 with row 3:
1 2 3 4 14 15 16 8 (was: 5 6 7 8) 9 10 11 12 (middle row stays in place) 6 7 8 16 (was: 13 14 15 16)
Wait, let me recalculate - the columns should be from y
to y + k - 1
:
- Column range: from 1 to 3 (inclusive)
Correcting the swaps:
j = 1
: Swapgrid[1][1]
(6) withgrid[3][1]
(14)j = 2
: Swapgrid[1][2]
(7) withgrid[3][2]
(15)j = 3
: Swapgrid[1][3]
(8) withgrid[3][3]
(16)
Final Result:
1 2 3 4 5 14 15 16 9 10 11 12 13 6 7 8
The submatrix has been flipped vertically:
- Original submatrix rows: [6,7,8], [10,11,12], [14,15,16]
- Flipped submatrix rows: [14,15,16], [10,11,12], [6,7,8]
Note that row 2 (containing 10,11,12) remains in its original position since it's the middle row of an odd-sized submatrix, and elements outside the submatrix (like 1,2,3,4,5,9,13) remain unchanged.
Solution Implementation
1class Solution:
2 def reverseSubmatrix(
3 self, grid: List[List[int]], x: int, y: int, k: int
4 ) -> List[List[int]]:
5 """
6 Reverses rows within a kΓk submatrix starting at position (x, y).
7 The submatrix rows are flipped vertically (top rows swap with bottom rows).
8
9 Args:
10 grid: 2D list representing the matrix
11 x: Starting row index of the submatrix
12 y: Starting column index of the submatrix
13 k: Size of the square submatrix (kΓk)
14
15 Returns:
16 Modified grid with reversed submatrix rows
17 """
18 # Iterate through the first half of the submatrix rows
19 for row_idx in range(x, x + k // 2):
20 # Calculate the corresponding row index from the bottom
21 # that should be swapped with the current row
22 mirror_row_idx = x + k - 1 - (row_idx - x)
23
24 # Swap all elements in the current row with the mirror row
25 # within the column range [y, y + k)
26 for col_idx in range(y, y + k):
27 grid[row_idx][col_idx], grid[mirror_row_idx][col_idx] = (
28 grid[mirror_row_idx][col_idx],
29 grid[row_idx][col_idx]
30 )
31
32 return grid
33
1class Solution {
2 /**
3 * Reverses a kΓk submatrix vertically (flips rows top to bottom)
4 * starting from position (x, y) in the given grid.
5 *
6 * @param grid The 2D integer array to modify
7 * @param x The starting row index of the submatrix
8 * @param y The starting column index of the submatrix
9 * @param k The size of the square submatrix to reverse
10 * @return The modified grid with the submatrix reversed
11 */
12 public int[][] reverseSubmatrix(int[][] grid, int x, int y, int k) {
13 // Iterate through the first half of the rows in the submatrix
14 for (int row = x; row < x + k / 2; row++) {
15 // Calculate the corresponding row from the bottom to swap with
16 int mirrorRow = x + k - 1 - (row - x);
17
18 // Swap all elements in the current row with the mirror row
19 for (int col = y; col < y + k; col++) {
20 // Perform the swap using a temporary variable
21 int temp = grid[row][col];
22 grid[row][col] = grid[mirrorRow][col];
23 grid[mirrorRow][col] = temp;
24 }
25 }
26
27 return grid;
28 }
29}
30
1class Solution {
2public:
3 /**
4 * Reverses a kΓk submatrix vertically (flip rows top to bottom)
5 * @param grid - The input 2D matrix to be modified
6 * @param x - Starting row index of the submatrix
7 * @param y - Starting column index of the submatrix
8 * @param k - Size of the square submatrix (kΓk)
9 * @return The modified grid with the submatrix reversed
10 */
11 vector<vector<int>> reverseSubmatrix(vector<vector<int>>& grid, int x, int y, int k) {
12 // Iterate through the first half of rows in the submatrix
13 for (int row = x; row < x + k / 2; row++) {
14 // Calculate the corresponding row from the bottom to swap with
15 int mirrorRow = x + k - 1 - (row - x);
16
17 // Swap elements in all columns of the current row with the mirror row
18 for (int col = y; col < y + k; col++) {
19 swap(grid[row][col], grid[mirrorRow][col]);
20 }
21 }
22
23 return grid;
24 }
25};
26
1/**
2 * Reverses a kΓk submatrix vertically (flips rows within the submatrix)
3 * @param grid - The 2D array to modify
4 * @param x - The starting row index of the submatrix
5 * @param y - The starting column index of the submatrix
6 * @param k - The size of the square submatrix (kΓk)
7 * @returns The modified grid with the submatrix reversed
8 */
9function reverseSubmatrix(grid: number[][], x: number, y: number, k: number): number[][] {
10 // Iterate through the first half of the rows in the submatrix
11 for (let currentRow = x; currentRow < x + Math.floor(k / 2); currentRow++) {
12 // Calculate the corresponding row from the bottom to swap with
13 const mirrorRow = x + k - 1 - (currentRow - x);
14
15 // Swap elements between the current row and its mirror row
16 for (let currentCol = y; currentCol < y + k; currentCol++) {
17 // Swap the elements using destructuring assignment
18 [grid[currentRow][currentCol], grid[mirrorRow][currentCol]] =
19 [grid[mirrorRow][currentCol], grid[currentRow][currentCol]];
20 }
21 }
22
23 return grid;
24}
25
Time and Space Complexity
The time complexity is O(k^2)
, where k
is the side length of the submatrix. This is because:
- The outer loop runs
k/2
times (fromx
tox + k//2
) - The inner loop runs
k
times (fromy
toy + k
) - Therefore, the total number of operations is
(k/2) * k = k^2/2
, which simplifies toO(k^2)
The space complexity is O(1)
. The algorithm only uses a constant amount of extra space for the loop variables i
, i2
, and j
, regardless of the input size. The swapping operation is performed in-place on the existing grid without allocating any additional data structures.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Row Iteration Range
A common mistake is iterating through all k
rows instead of just the first half, which would cause each pair of rows to be swapped twice, resulting in no change to the matrix.
Incorrect approach:
# This swaps each pair twice, undoing the operation
for row_idx in range(x, x + k): # Wrong! Goes through all k rows
mirror_row_idx = x + k - 1 - (row_idx - x)
# Swap logic...
Correct approach:
# Only iterate through the first half of rows
for row_idx in range(x, x + k // 2): # Correct! Only first half
mirror_row_idx = x + k - 1 - (row_idx - x)
# Swap logic...
2. Off-by-One Error in Mirror Row Calculation
Another frequent error is forgetting to subtract 1 when calculating the last row index of the submatrix, leading to accessing rows outside the intended submatrix.
Incorrect formula:
# This accesses row x + k, which is outside the submatrix mirror_row_idx = x + k - (row_idx - x) # Wrong! Missing -1
Correct formula:
# Properly calculates the mirror row within bounds mirror_row_idx = x + k - 1 - (row_idx - x) # Correct!
3. Modifying Grid While Iterating Without Proper Swapping
Some might attempt to assign values directly without swapping, which would overwrite data before it's moved to its correct position.
Incorrect approach:
# This loses the original value of grid[row_idx][col_idx]
for row_idx in range(x, x + k // 2):
mirror_row_idx = x + k - 1 - (row_idx - x)
for col_idx in range(y, y + k):
grid[row_idx][col_idx] = grid[mirror_row_idx][col_idx] # Data loss!
grid[mirror_row_idx][col_idx] = grid[row_idx][col_idx] # Already overwritten!
Correct approach:
# Proper simultaneous swap preserves both values grid[row_idx][col_idx], grid[mirror_row_idx][col_idx] = ( grid[mirror_row_idx][col_idx], grid[row_idx][col_idx] )
4. Assuming Square Matrix Instead of Submatrix
A conceptual error is treating the entire grid as the target for flipping rather than just the k Γ k
submatrix starting at (x, y)
.
Prevention: Always ensure your row iteration is range(x, x + k // 2)
and column iteration is range(y, y + k)
, not range(0, m // 2)
and range(0, n)
.
Which data structure is used to implement priority queue?
Recommended Readings
Tech Interview Pattern Two Pointers Introduction If you prefer videos here's a super quick introduction to Two Pointers div class responsive iframe iframe src https www youtube com embed xZ4AfXHQ1VQ title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture allowfullscreen iframe div Two pointers is a common interview
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Donβt Miss This!