给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
解题思路:
我第一看看到这个题目就想用状态机去做,因为在这个遍历过程中只有两种状态:向右上移动,向左下移动。只要将状态转换条件设置好就OK了。
起始状态是右上,从右上转换到左下有两种情况,1.到第一行没法向上了就向右移动一位转为左下状态。2.到最右边了没法向右的就向下移动一位转为左下状态。
同理可得从左下状态转为右上状态也有两种情况,1.到最后一行没法向下了就向右移动一位转为右上状态。2.到最左边了没法向左的就向下移动一位转为右上状态。
代码如下:
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
static const int RIGHT_UP = 0;//右上状态
static const int LEFT_DOWN = 1;//左下状态
int STATE = RIGHT_UP;//初始为右上状态
vector<int> out;//保存结果
int i = 0, j = 0;//i为行,j为列
int M = matrix.size();
if (!M)
{
return out;
}//判断输入是否为空
int N = matrix[0].size();
while (i <= M-1 &&j <= N-1)
{
switch (STATE)
{
case RIGHT_UP:
out.push_back(matrix[i][j]);
if (i == 0 ||j==N-1)//需要转换状态的两种情况
{
if (j == N - 1)//到最右边
{
i++;
}
else
{
j++;
}
STATE = LEFT_DOWN;//状态转换
}
else
{
i = i - 1;
j = j + 1;
}
break;
case LEFT_DOWN:
out.push_back(matrix[i][j]);
if(i == M-1 &&j<N-1)
{
j++;
STATE = RIGHT_UP;
}
else if (j == 0 &&i<M-1)
{
i++;
STATE = RIGHT_UP;
}
else
{
i++;
j--;
}
break;
}
}
return out;
}
};
看别人的题解发现的规律:在相同线上移动时,行和列的和不变,
vector<int> findDiagonalOrder(vector<vector<int>>& matrix)
{
vector<int> nums;
int m = matrix.size();
if (m == 0) return nums;
int n = matrix[0].size();
if (n == 0) return nums;
bool bXFlag = true;
for (int i = 0; i < m + n; i++)
{
int pm = bXFlag ? m : n;
int pn = bXFlag ? n : m;
int x = (i < pm) ? i : pm - 1;
int y = i - x;
while (x >= 0 && y < pn)
{
nums.push_back(bXFlag ? matrix[x][y] : matrix[y][x]);
x--;
y++;
}
bXFlag = !bXFlag;
}
return nums;
}