LeetCode链接:对角线遍历
路径法,这是我个人的称呼。
有两种方向,往右上为正方向,往左下为反方向。从(0,0)开始,循着实际路径,每当走到边界时,方向翻转,并定位下次开始走路的索引。示意图如下
- 往右上为正方向,前进时,每次前进一步,rowIndex--,colIndex++。共有三种边界情况,即图中圆圈中的1 2 3。
第1种情况:方向取反,行索引重置为0,列索引+1,即从1走到2。
第2种情况:方向取反,行索引重置为1,列索引重置到边界,即从5走到10。
第3种情况:方向取反,行索引向下递增1,列索引重置到边界,即从15走到20。
- 往左下为反方向,前进时,每次前进一步,rowIndex++,colIndex--。也有三种边界情况,即图中圆圈中的4 5 6。
第4种情况:方向取反,列索引重置为0,行索引+1,即从6走到11。
第5种情况:方向取反,列索引重置为1,行索引重置到边界,即从16走到17。
第6种情况:方向取反,列索引向下递增1,行索引重置到边界,即从18走到19。
根据这个思路,有如下代码
vector<int> findDiagonalOrder(const vector<vector<int>>& mat)
{
int m = mat.size();
int n = mat[0].size();
vector<int> ret;
int rowIndex = 0, colIndex = 0;
//标识当前是在前进还是后退,即是往右上去还是左下去,默认是前进
bool forward = true;
//先将第一个元素加入到列表
ret.push_back(mat[rowIndex][colIndex]);
while (ret.size() != m * n)
{//添加的元素不够数,一直走路
//开始走路
if (forward)
{//右上前进
rowIndex--;
colIndex++;
if (rowIndex == -1 && colIndex < n)
{//第1种情况
forward = false;
rowIndex = 0;
}
else if (rowIndex == -1 && colIndex == n)
{//第2种情况
forward = false;
rowIndex = 1;
colIndex -= 1;
}
else if (rowIndex >= 0 && colIndex == n)
{//第3种情况
forward = false;
rowIndex += 2;
colIndex--;
}
}
else
{//左下前进
rowIndex++;
colIndex--;
if (colIndex == -1 && rowIndex < m)
{//第4种情况
forward = true;
colIndex = 0;
}
else if (colIndex == -1 && rowIndex == m)
{//第5种情况
forward = true;
colIndex = 1;
rowIndex -= 1;
}
else if (colIndex >= 0 && rowIndex == m)
{//第6种情况
forward = true;
colIndex += 2;
rowIndex--;
}
}
//每次走路,都将脚下元素加入到结果列表中
ret.push_back(mat[rowIndex][colIndex]);
}
return ret;
}
LeetCode执行测试: