📌  相关文章
📜  使用方向跟踪方法以螺旋形式打印给定矩阵

📅  最后修改于: 2021-04-21 21:42:40             🧑  作者: Mango

给定二维矩阵mat [] [] ,任务是将其以螺旋形式打印。

例子:

方法:使用方向方法可以轻松解决此问题。由于我们从东方向开始,因此无论何时下一个索引无效(超出矩阵)或更早访问时,都始终向右转。遵循的方向是东->南->西->北->…,mat [0] [0]开始,到矩阵的所有元素都遍历后最终结束。

下面是上述方法的实现:

// C++ implementation of the approach
#include 
using namespace std;
#define R 5
#define C 5
  
enum direction { east,
                 west,
                 north,
                 south };
  
// Function to set the new direction on turning
// right from the current direction
void turnright(enum direction& c_direction)
{
    switch (c_direction) {
    case east:
        c_direction = south;
        break;
    case west:
        c_direction = north;
        break;
    case north:
        c_direction = east;
        break;
    case south:
        c_direction = west;
        break;
    }
}
  
// Function to return the next possible cell
// indexes with current direction
pair next(int i, int j,
                    const enum direction& c_direction)
{
    switch (c_direction) {
    case east:
        j++;
        break;
    case west:
        j--;
        break;
    case north:
        i--;
        break;
    case south:
        i++;
        break;
    }
    return pair(i, j);
}
  
// Function that returns true
// if arr[i][j] is a valid index
bool isvalid(const int& i, const int& j)
{
    if (i < R && i >= 0 && j >= 0 && j < C)
        return true;
    return false;
}
  
// Function that returns true if arr[i][j]
// has already been visited
bool alreadyVisited(int& i, int& j, int& mini, int& minj,
                    int& maxi, int& maxj)
{
  
    // If inside the current bounds then
    // it has not been visited earlier
    if (i >= mini && i <= maxi && j >= minj && j <= maxj)
        return false;
    return true;
}
  
// Function to update the constraints of the matrix
void ConstraintWalls(int& mini, int& minj, int& maxi,
                     int& maxj, direction c_direction)
{
  
    // Update the constraints according
    // to the direction
    switch (c_direction) {
    case east:
        mini++;
        break;
    case west:
        maxi--;
        break;
    case north:
        minj++;
        break;
    case south:
        maxj--;
        break;
    }
}
  
// Function to print the given matrix in the spiral form
void printspiral(int arr[R][C])
{
  
    // To store the count of all the indexes
    int count = 0;
  
    // Starting direction is East
    enum direction current_direction = east;
  
    // Boundary constraints in the matrix
    int mini = 0, minj = 0, maxi = R - 1, maxj = C - 1;
    int i = 0, j = 0;
  
    // While there are elements remaining
    while (count < (R * C)) {
  
        // Print the current element
        // and increment the count
        cout << arr[i][j] << " ";
        count++;
  
        // Next possible cell if direction remains the same
        pair p = next(i, j, current_direction);
  
        // If current cell is already visited or is invalid
        if (!isvalid(p.first, p.second)
            || alreadyVisited(p.first, p.second, mini, minj, maxi, maxj)) {
  
            // If not visited earlier then only change the constraint
            if (!alreadyVisited(i, j, mini, minj, maxi, maxj))
                ConstraintWalls(mini, minj, maxi, maxj, current_direction);
  
            // Change the direction
            turnright(current_direction);
  
            // Next indexes with new direction
            p = next(i, j, current_direction);
        }
  
        // Next row and next column
        i = p.first;
        j = p.second;
    }
}
  
// Driver code
int main()
{
    int arr[R][C];
  
    // Fill the matrix
    int counter = 1;
    for (int i = 0; i < R; i++)
        for (int j = 0; j < C; j++)
            arr[i][j] = counter++;
  
    // Print the spiral form
    printspiral(arr);
  
    return 0;
}
输出:
1 2 3 4 5 10 15 20 25 24 23 22 21 16 11 6 7 8 9 14 19 18 17 12 13

时间复杂度: O(R * C)
空间复杂度: O(1)