MATRIX › MATRIX TRANSFORMATION AND MODIFICATION
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →Read the grid from left to right across each row, then continue at the first cell of the next row. Under the shifting rule, every cell moves to the next position in exactly this order, and the last cell moves back to the first position. So the two-dimensional movement is a one-dimensional circular shift in row-major order.
After one shift, the final element becomes the first element. After k shifts, the last k elements become the prefix and the remaining elements follow them. A complete cycle of m x n shifts changes nothing, so reducing k modulo the total number of cells removes work without changing the answer.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | O(mn) | The grid is flattened once, the rotated sequence is filled once, and the answer is reshaped once. Each of the mn cells participates in a constant number of assignments, so no cell causes repeated work. |
| Space | O(mn) extra | The flat, rotated, and answer structures together hold O(mn) values; the returned answer is required output and is excluded from the extra-space bound. The bound is still O(mn) for every valid rectangular shape, including a single row or a single column. |
#include <vector>
using namespace std;
class Solution {
public:
vector<vector<int>> shiftGrid(vector<vector<int>>& grid, int k) {
int m = grid.size();
int n = grid[0].size();
int total = m * n;
k %= total;
if (k == 0) return grid;
vector<int> flat(total);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
flat[i * n + j] = grid[i][j];
}
}
int start = total - k;
vector<int> rotated(total);
for (int i = 0; i < total; ++i) {
rotated[i] = flat[(start + i) % total];
}
vector<vector<int>> answer(m, vector<int>(n));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
answer[i][j] = rotated[i * n + j];
}
}
return answer;
}
};The key line is start = total - k. For a right rotation by k, the new first element is the old element k positions before the end. The expression (start + i) % total then walks forward through the old sequence and wraps around exactly once. Keeping rotation and reshaping as separate phases makes the direction visible and avoids mixing two-dimensional coordinates with circular movement.