给定二维矩阵mat [] [] ,任务是将其以螺旋形式打印。
例子:
Input: mat[][] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}}
Output: 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
Input: mat[][] = {
{1, 2, 3, 4, 5, 6},
{7, 8, 9, 10, 11, 12},
{13, 14, 15, 16, 17, 18}}
Output: 1 2 3 4 5 6 12 18 17 16 15 14 13 7 8 9 10 11
方法:使用方向方法可以轻松解决此问题。由于我们从东方向开始,因此无论何时下一个索引无效(超出矩阵)或更早访问时,都始终向右转。遵循的方向是东->南->西->北->…,从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)