problems(cpp): add “59. Spiral Matrix II”
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
7147f610a2
commit
a1a9c876e6
1 changed files with 102 additions and 0 deletions
102
problems/spiral-matrix-ii.cpp
Normal file
102
problems/spiral-matrix-ii.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
class Solution {
|
||||
struct indices {
|
||||
int x;
|
||||
int y;
|
||||
|
||||
bool operator==(const indices& other) const = default;
|
||||
indices& operator+=(const indices& other) {
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend indices operator+(indices left, const indices& right) {
|
||||
return left += right;
|
||||
}
|
||||
|
||||
int& operator[](std::vector<std::vector<int>>& mat) const {
|
||||
return mat[y][x];
|
||||
}
|
||||
};
|
||||
|
||||
struct spiral_indices {
|
||||
spiral_indices(const std::vector<std::vector<int>>& matrix)
|
||||
: x_bounds{-1, static_cast<int>(matrix.size() ? matrix[0].size() : 0)},
|
||||
y_bounds{-1, static_cast<int>(matrix.size())} {}
|
||||
|
||||
bool done() const { return !in_bounds(idx); }
|
||||
|
||||
spiral_indices& operator++() {
|
||||
// update bounds and change the direction if cannot move
|
||||
if (!in_bounds(idx + d)) {
|
||||
// change the direction
|
||||
d = {-d.y, d.x};
|
||||
|
||||
// get the magnitude of the vector
|
||||
auto flat_d = d.x + d.y;
|
||||
|
||||
// decide whether we're moving x or y bounds
|
||||
auto& bounds = d.x ? x_bounds : y_bounds;
|
||||
if (flat_d > 0) {
|
||||
bounds.x++;
|
||||
} else {
|
||||
bounds.y--;
|
||||
}
|
||||
}
|
||||
|
||||
idx += d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int& operator[](std::vector<std::vector<int>>& mat) const {
|
||||
return idx[mat];
|
||||
}
|
||||
|
||||
private:
|
||||
indices idx{0, 0};
|
||||
indices d{1, 0};
|
||||
indices x_bounds, y_bounds;
|
||||
|
||||
bool in_bounds(const indices& idx) const {
|
||||
return (x_bounds.x < idx.x && idx.x < x_bounds.y) &&
|
||||
(y_bounds.x < idx.y && idx.y < y_bounds.y);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
std::vector<std::vector<int>> generateMatrix(int n) {
|
||||
auto length = static_cast<std::size_t>(n);
|
||||
std::vector<std::vector<int>> spiral{length, std::vector<int>(length, 0)};
|
||||
|
||||
int i = 1;
|
||||
for (spiral_indices idx{spiral}; !idx.done(); ++idx) {
|
||||
idx[spiral] = i++;
|
||||
}
|
||||
|
||||
return spiral;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Solution s;
|
||||
|
||||
assert((s.generateMatrix(0) == std::vector<std::vector<int>>{}));
|
||||
assert((s.generateMatrix(1) == std::vector<std::vector<int>>{{1}}));
|
||||
assert(
|
||||
(s.generateMatrix(2) == std::vector<std::vector<int>>{{1, 2}, {4, 3}}));
|
||||
|
||||
for (auto&& row : s.generateMatrix(3)) {
|
||||
for (auto x : row) std::cout << x << " ";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
assert((s.generateMatrix(3) ==
|
||||
std::vector<std::vector<int>>{{1, 2, 3}, {8, 9, 4}, {7, 6, 5}}));
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue