Given an integern, generate a square matrix filled with elements from 1 ton2in spiral order.
For example,
Givenn=3,
You should return the following matrix:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
Complexity: O(n) time and space The Idea: Had fun with this one. Basically I've defined 4 functions that do one thing - iterate left, right, up and down. Then I wrap these up in a vector and invoke them over and over again over a wrapping modulus with the right parameterizations. I thought it was pretty elegant.
vector<vector<int>> generateMatrix(int n){usingdv=vector<vector<int>>;if (!n) returndv(); dv spiral_m(n,vector<int>(n));int incr =1;auto right = [&](int&row,int&col,dv&spiral_m,int n,int&incr) {while (col < n &&spiral_m[row][col] ==0) {spiral_m[row][col] = incr++; col++; } // finished - so backtrack once and move down 1 col--; row++; };auto down = [&](int&row,int&col,dv&spiral_m,int n,int&incr) {while (row < n &&spiral_m[row][col] ==0) {spiral_m[row][col] = incr++; row++; } // finished - so backtrack once and left 1 row--; col--; };auto left = [&](int&row,int&col,dv&spiral_m,int n,int&incr) {while (col >=0&&spiral_m[row][col] ==0) {spiral_m[row][col] = incr++; col--; } // finished - so backtrack once and move up 1 col++; row--; };auto up = [&](int&row,int&col,dv&spiral_m,int n,int&incr) {while (row >=0&&spiral_m[row][col] ==0) {spiral_m[row][col] = incr++; row--; } // finished - so backtrack once and move right 1 row++; col++; }; vector<std::function<void(int&,int&, dv &,int,int&)>> functors = {right, down, left, up};int row =0, col =0;int function_wrapper =0; // the number of time to loop in a spiral grows at n+n-1; // consider the pattern for size n: // // n | loop // 1 | 1 // 2 | 3 // 3 | 5 // 5 | 7int num_times_to_loop = (2* n) -1;while (num_times_to_loop) {functors.at(function_wrapper %functors.size())(row, col, spiral_m, n, incr); function_wrapper++; num_times_to_loop--; }return spiral_m;}
// some testing
int main(int argc, char **argv)
{
for (int i : {0,1,2,3,4,5,6,7,8,9})
print2d(generateMatrix(i));
}