三种方法遍历螺旋数组(dfs四个方向模拟层层模拟)
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三种方法遍历螺旋数组(dfs四个方向模拟层层模拟)相关的知识,希望对你有一定的参考价值。
题目
dfs解决
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
m = matrix.size()-1;
n = matrix[0].size()-1;
dfs(matrix,0,0);
return res;
}
private:
int m;
int n;
//用于记录遍历的是第几个圈
int count = 0;
vector<int>res;
void dfs(vector<vector<int>>& matrix,int i,int j){
//用于终止条件
if(res.size()==matrix.size()*matrix[0].size())
return;
//遍历上方一横条
if(j<n-count&&i==count){
res.push_back(matrix[i][j]);
dfs(matrix,i,j+1);
}//遍历右边一竖条
else if(j==n-count&&i<m-count){
res.push_back(matrix[i][j]);
dfs(matrix,i+1,j);
}//遍历下方一横条
else if(i==m-count&&j-count>0){
res.push_back(matrix[i][j]);
dfs(matrix,i,j-1);
}//遍历左边一竖条,并且进行特殊判断(当遍历到左边一竖条的最后一个元素的时候需要换一圈进行遍历(故此时更新count并换情况dfs下一层))
else if(j==count&&i-count>0){
res.push_back(matrix[i][j]);
if(j==count&&i-count==1){
count++;
dfs(matrix,i,j+1);
}else
dfs(matrix,i-1,j);
}else{
//用于处理特殊情况:当遍历不是环形,而是只有一层的时候会把最后一个元素漏掉
res.push_back(matrix[i][j]);
}
}
};
从外到内层层模拟
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) {
return {};
}
int rows = matrix.size(), columns = matrix[0].size();
vector<int> order;
//left right用于记录每层的左右边界,top和bottom用于记录每层的上下边界
int left = 0, right = columns - 1, top = 0, bottom = rows - 1;
while (left <= right && top <= bottom) {
//遍历每层的时候不要改变各层边界的指标,在最后才进行改变,表示进入到下一层进行遍历
//遍历上面的横向
for (int column = left; column <= right; column++) {
order.push_back(matrix[top][column]);
}//遍历右边的竖向
for (int row = top + 1; row <= bottom; row++) {
order.push_back(matrix[row][right]);
}//根据判断情况看是否需要遍历左边和下面的竖向和横向
if (left < right && top < bottom) {
for (int column = right - 1; column > left; column--) {
order.push_back(matrix[bottom][column]);
}
for (int row = bottom; row > top; row--) {
order.push_back(matrix[row][left]);
}
}
//更新每层的相关信息
left++;
right--;
top++;
bottom--;
}
return order;
}
};
依靠四个方向模拟
class Solution {
private:
//对应不同方向遍历-->向右、向下、向左、向上
static constexpr int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) {
return {};
}
int rows = matrix.size(), columns = matrix[0].size();
//用于记录已经遍历过的位置
vector<vector<bool>> visited(rows, vector<bool>(columns));
int total = rows * columns;
//初始要返回数组的长度,以便以该数组为主导对目标数组遍历
vector<int> order(total);
int row = 0, column = 0;
//用于确定下一个遍历方向的标记,可以通过对4取模得到四种遍历方向的连续变化。
int directionIndex = 0;
for (int i = 0; i < total; i++) {
order[i] = matrix[row][column];
visited[row][column] = true;
//保存下一个遍历方向的位置,用于判断下一次遍历是否需要换方向
int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
//一旦下一个遍历的位置越界,或者是下一个要遍历的位置曾经被遍历过,则下一个位置不能取,则需要换方向遍历。
if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) {
directionIndex = (directionIndex + 1) % 4;
}
//更新真正的下一个遍历方向
row += directions[directionIndex][0];
column += directions[directionIndex][1];
}
return order;
}
};
以上是关于三种方法遍历螺旋数组(dfs四个方向模拟层层模拟)的主要内容,如果未能解决你的问题,请参考以下文章