刷LeetCode题时做到的一到题(曾经面试一家大型互联网公司时遇到过),给定数N,输出他的螺旋矩阵,列如:
如:NUM=3 NUM=4
01 08 07 01 12 11 10
02 08 06 02 13 16 09
03 04 05 03 14 15 08
04 05 06 07
其实这道题如果准确的发现了螺旋矩阵的规律问题也就迎刃而解了,找到关键的拐点,按照螺旋的顺序依次将二维数组中的值填上输出即可实现螺旋矩阵了:
- 1号转弯处:行号和列号之和为N-1
- 2号转弯处:行号和列号相等
- 3号转弯处:行号和列号之差为1
设定起点在(0,0)处,用orient来控制螺旋的方向,用就j,k分别控制行列号,顺着螺旋的方向依次给二维数组赋值,我们就可以将螺旋矩阵的数据装入二维数组中,然后循环遍历输出即可:
public static void PrintOut(int n)
{
int[,] array = new int[n,n];
//螺旋方向控制:0 向下(列号不变行号+1);
//1 向右(行号不变,列号+1);
//2 向上 (列号不变,行号-1),
//3 向左(行号不变,列号-1)
int orient = 0;
int k = 0;
int j=0;//设置起点为(0,0)
for (int i = 0; i < n * n; i++)//遍历一次数组
{
array[j,k] = i;
//右上到左下对角线转角处:
if (j + k == n - 1)
{
if (j > k)//左下转角
{
orient = 1;
}
else
{
orient = 3;
}
}
else if (k == j && k >= n / 2)//右下角
{
orient = 2;
}
else if (j == k - 1 && k <= n / 2)//左上角
{
orient = 0;
}
if (orient == 0)
{
j += 1;
}
else if (orient == 1)
{
k += 1;
}
else if (orient == 2)
{
j -= 1;
}
else if (orient == 3)
{
k -= 1;
}
}
for (int i = 0; i < n; i++)
{
for (int z = 0; z < n; z++)
{
if (array[i, z] < 10)
{
Console.Write(" ");
}
Console.Write(array[i, z] + " ");
}
Console.WriteLine(string.Empty);
}
}
输出结果:
如果想要输出顺时针螺旋矩阵,根据以上说明,不难发现只是关键的拐点数据有细微的差别:
- 右下对角线处行号和列号相等
- 左上对角线转角柱行列号之差为1
- 右上至左下对角线处行号和列号之和为n-1
顺时针螺旋矩阵
如下代码所示,只需要将行列拐点处的逻辑稍加修改即可实现顺时针螺旋矩阵:
public static void PrintOut(int n)
{
int[,] array = new int[n,n];
//螺旋方向控制:0 向下(列号不变行号+1);
//1 向右(行号不变,列号+1);
//2 向上 (列号不变,行号-1),
//3 向左(行号不变,列号-1)
int orient = 1;
int k = 0;
int j=0;//设置起点为(0,0)
for (int i = 0; i < n * n; i++)//遍历一次数组
{
array[j,k] = i;
//右上到左下对角线转角处:
if (j + k == n - 1)
{
if (j > k)//左下转角
{
orient = 2;
}
else
{
orient = 0;
}
}
else if (j - 1 == k && j <= n / 2)//左上角
{
orient = 1;
}
else if (j == k && j >= n / 2)//右下角
{
orient = 3;
}
if (orient == 0)
{
j += 1;
}
else if (orient == 1)
{
k += 1;
}
else if (orient == 2)
{
j -= 1;
}
else if (orient == 3)
{
k-= 1;
}
}
for (int i = 0; i < n; i++)
{
for (int z = 0; z < n; z++)
{
if (array[i, z] < 10)
{
Console.Write(" ");
}
Console.Write(array[i, z] + " ");
}
Console.WriteLine(string.Empty);
}
}
}
输出结果: