M x N要素(M行、N列)の行列が与えられた場合、次の図に示すように、この行列のすべての要素を斜めトラバースの順序で返します。
問題解決のアイデア:
このトピックを最初に見たとき、このトラバーサルプロセスには2つの状態(右上への移動と左下への移動)しかないため、状態マシンでそれを実行したいと考えました。状態遷移条件が設定されていれば問題ありません。
開始状態は右上で、右上から左下に切り替わるケースが2つあります。1。最初の行が上に移動できない場合は、1ビット右に移動して左下の状態にします。2.右端に到達したとき、右に移動できない場合は、1ビット下に移動して左下に回します。
同様に、左下の状態から右上の状態に変化する場合も2つあります1.最終行が下に移動できなくなった後、1ビット右に移動して右上の状態になります。2.左端に到達すると、左に移動して1ビット下の右上に移動することはできません。
コードは次のとおりです。
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;
}