所谓内螺旋矩阵,即矩阵中的元素,以内部某点为起点,依据逆时针或顺时针的顺序依次旋转将值逐渐增加,并最后旋转到矩阵的最外围。
这篇博客所考虑的旋转方式为逆时针旋转,因为网上关于顺时针的已经有了,也就没有必要再去写了。我们以一个
4
×
4
4\times 4
4×4的矩阵为例子,如下所示,
[
10
9
8
7
11
2
1
6
12
3
4
5
13
14
15
16
]
\begin{bmatrix} 10 & 9 & 8 & 7\\ 11 & 2 & 1 & 6\\ 12 & 3 & 4 & 5\\ 13 & 14 & 15 & 16 \end{bmatrix} \
⎣⎢⎢⎡10111213923148141576516⎦⎥⎥⎤
其旋转的方式可以表示为
对于这样的一个问题,其实其本质就是一个线性规划问题,相信大家都有学过线性规划。在上图中的旋转方式无非有四种,上下左右,而且同方向的移动都是很靠近的,如
3
>
4
,
14
>
15
3>4,14>15
3>4,14>15等。
因此,考虑线性规划,我们只要将其划分为四个部分,并在不同部分内进行不同的移动操作即可以解决上述问题,如下图所示。
上图中的’左’即表明在该区间内的点朝左运动。
在得到了上述图形后,我们的工作也完成了一大办了,接下来的就是如何将这个线性规划给写出来。在写线性规划的时候,有个问题很头疼,那就是=
什么时候可以取,什么时候不可以取,这就需要我们在构造线性规划时选取一组数据来带入进行尝试,本人选择了上面的
4
×
4
4\times 4
4×4的矩阵中的位移点来进行测试的,构造出的线性规划结果如下
i
<
j
a
n
d
i
+
j
≤
3
左
移
(
j
−
1
)
i
≥
j
a
n
d
i
+
j
<
3
下
移
(
i
+
1
)
i
≥
j
a
n
d
i
+
j
≥
3
右
移
(
j
+
1
)
i
<
j
a
n
d
i
+
j
>
3
上
移
(
i
−
1
)
\begin{array}{l} i< j\ \ and\ \ i+j\leq 3\ \ 左移( j-1) \ \\ i\geq j\ \ and\ \ i+j< 3\ \ 下移( i+1) \ \\ i\geq j\ \ and\ \ i+j\geq 3\ \ 右移( j+1) \ \\ i< j\ \ and\ \ i+j >3\ \ 上移( i-1) \ \end{array}
i<j and i+j≤3 左移(j−1) i≥j and i+j<3 下移(i+1) i≥j and i+j≥3 右移(j+1) i<j and i+j>3 上移(i−1)
既然线性规划的表达式都出来了,那代码还不是信手拈来。
def interSpiralMatrix(size):
matrix = [[None] * size for i in range(size)]
i, j, side = int((size-1)/2), int(size/2), size - 1
for item in range(1, size ** 2 + 1):
# print(i,j)
matrix[i][j] = item
if (i < j) and (i + j <= side):
j = j - 1
elif (i >= j) and (i + j < side):
i = i + 1
elif (i >= j) and (i + j >= side):
j = j + 1
elif (i < j) and (i + j > side):
i = i - 1
for item in matrix:
for tmp in item:
print('%2d ' % tmp, end = '')
print()
使用上述代码,我们可以得到5阶和6阶的内螺旋矩阵为
5阶内螺旋矩阵:
17 16 15 14 13
18 5 4 3 12
19 6 1 2 11
20 7 8 9 10
21 22 23 24 25
6阶内螺旋矩阵:
26 25 24 23 22 21
27 10 9 8 7 20
28 11 2 1 6 19
29 12 3 4 5 18
30 13 14 15 16 17
31 32 33 34 35 36
好好学习,天天向上。