Spiral Matrix
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
You should return [1,2,3,6,9,8,7,4,5]
.
Spiral Matrix II
Given an integer n, generate a square matrix filled with elements from 1 ton2 in spiral order.
For example,
Given n = 3
,
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
思路:
光标转移有四个状态,依次是向右,向下,向左,向上。光标转移状态的变化根据三个条件:1. 到达上界(n)2.到达下界(0)3.光标的下一个位置已经被填满。据此编码。
题解:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int> > &matrix) {
enum { VISITED = -1 };
if (matrix.size()==0)
return vector<int>();
const int M = matrix.size();
const int N = matrix[0].size();
int cursorX = 0;
int cursorY = 0;
int incrX = 1;
int incrY = 0;
int nextX, nextY;
int LEFT = 0, RIGHT = N;
int TOP = 0, BOTTOM = M;
auto valid_X=[&](const int c) -> bool {
return c >= LEFT && c < RIGHT;
};
auto valid_Y=[&](const int c) -> bool {
return c >= TOP && c < BOTTOM ;
};
auto valid_state=[&]()->bool {
return valid_X(nextX) && valid_Y(nextY);
};
auto next_state=[&]() {
switch(incrX * 2 + incrY)
{
case 2: // moving right
++TOP;
incrX = 0, incrY = 1;
break;
case -2: // moving left
--BOTTOM;
incrX = 0, incrY = -1;
break;
case 1: // moving down
--RIGHT;
incrX = -1, incrY = 0;
break;
case -1: // moving up
++LEFT;
incrX = 1, incrY = 0;
break;
}
};
auto next_pos=[&]() {
nextX = cursorX + incrX;
nextY = cursorY + incrY;
};
vector<int> ret;
ret.reserve(M * N);
for(int i = 0; i < M * N; ++i)
{
ret.push_back(matrix[cursorY][cursorX]);
next_pos();
if (!valid_state())
{
next_state();
next_pos();
}
cursorX = nextX;
cursorY = nextY;
}
return ret;
}
};
class Solution {
public:
vector<vector<int> > generateMatrix(int n) {
enum { UNUSED = -1 };
vector<vector<int>> matrix(n);
for(auto& row : matrix)
{
row.resize(n);
fill(begin(row), end(row), UNUSED);
}
int cursorX = 0;
int cursorY = 0;
int incrX = 0;
int incrY = 1;
int nextX, nextY;
auto valid_pos=[&](const int c) -> bool {
return c >= 0 && c < n;
};
auto valid_state=[&]()->bool {
return valid_pos(nextX) &&
valid_pos(nextY) &&
matrix[nextX][nextY] == UNUSED;
};
auto next_state=[&]() {
switch(incrX * 2 + incrY)
{
case 1:
incrX = 1, incrY = 0;
break;
case 2:
incrX = 0, incrY = -1;
break;
case -1:
incrX = -1, incrY = 0;
break;
case -2:
incrX = 0, incrY = 1;
break;
}
};
auto next_pos=[&]() {
nextX = cursorX + incrX;
nextY = cursorY + incrY;
};
for(int i = 1; i <= n * n; ++i)
{
matrix[cursorX][cursorY] = i;
// increment the cursor
next_pos();
if (!valid_state())
{
next_state();
next_pos();
}
cursorX = nextX;
cursorY = nextY;
}
return matrix;
}
};