Cyclically Rotating a Grid LeetCode solution in C++

1
const vector<pair<int, int>> directions{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
2

3
class Solution {
4
protected:
5
int n, m;
6

7
int whichLayer(int x, int y) {
8
if (x < 0 || y < 0 || x >= n || y >= m) return -1;
9
int i = min(x, n - x - 1);
10
int j = min(y, m - y - 1);
11
return min(i, j);
12
}
13

14
void nextPos(int x, int y, int dir, int &nx, int &ny) {
15
nx = x + directions[dir].first;
16
ny = y + directions[dir].second;
17
}
18

19
// Go to next position in the current layer (in clockwise order)
20
void advancePosition(int &x, int &y, int &d) {
21
int nx, ny;
22
nextPos(x, y, d, nx, ny);
23
if (whichLayer(nx, ny) != whichLayer(x, y)) {
24
// Change direction
25
d = (d + 1) % 4;
26
nextPos(x, y, d, nx, ny);
27
}
28
x = nx;
29
y = ny;
30
}
31

32
public:
33
vector<vector<int>> rotateGrid(vector<vector<int>> &grid, int k) {
34
// Check validity of the arguments
35
if (grid.empty()) throw invalid_argument("empty grid");
36
m = grid.size();
37
n = grid[0].size();
38
if (n == 0) throw invalid_argument("empty grid");
39
if (k < 0) throw invalid_argument("negative k not accepted");
40

41
// Trivial case
42
if (k == 0) return grid;
43

44
const int L = min(n, m) / 2;
45
for (int l = 0; l < L; l++) {
46
vector<int> v;
47

48
// Flatten a layer from grid into a vector
49
int j = l, i = l; // start position
50
int d = 0; // direction
51
do {
52
v.push_back(grid[j][i]);
53
advancePosition(i, j, d);
54
} while (!(i == l && j == l)); // until the start position is reached
55

56
// Unflatten rotated vector back into the grid
57
j = l;
58
i = l; // start position
59
d = 0; // direction
60
int off = k % v.size();
61
do {
62
grid[j][i] = v[off];
63
off = (off + 1) % v.size();
64
advancePosition(i, j, d);
65
} while (!(i == l && j == l)); // until the start position is reached
66
}
67

68
return grid;
69
}
70
};

0

WPM •0 •0

100%

ACC •0 •0

0s

TIME •0