problems(cpp): add “54. Spiral Matrix”
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
e5c5a79e70
commit
7147f610a2
1 changed files with 91 additions and 0 deletions
91
problems/spiral-matrix.cpp
Normal file
91
problems/spiral-matrix.cpp
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#include <cassert>
|
||||||
|
#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[](const 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[0].size())},
|
||||||
|
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[](const 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<int> spiralOrder(const std::vector<std::vector<int>>& matrix) {
|
||||||
|
std::vector<int> spiral;
|
||||||
|
|
||||||
|
for (spiral_indices idx{matrix}; !idx.done(); ++idx) {
|
||||||
|
spiral.push_back(idx[matrix]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spiral;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Solution s;
|
||||||
|
|
||||||
|
assert((s.spiralOrder({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}) ==
|
||||||
|
std::vector{1, 2, 3, 6, 9, 8, 7, 4, 5}));
|
||||||
|
assert((s.spiralOrder({{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}) ==
|
||||||
|
std::vector{1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7}));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue