1. 题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

2. 思路分析

既然是顺时针打印,其实就是由外向内一圈圈打印,将过程分为 2 步:

第一步:printMatrix函数,确定要打印的圈的左上角坐标(比较简单)

第二步:printMatrixInCircle函数,根据左上角坐标,顺时针打印这一圈的信息。这个过程又分为四步:左上 -> 右上 -> 右下 -> 左下 -> 左上。

3. 代码实现

如果觉得,函数printMatrixInCircle的条件判断不清楚,可以配合下面这张图一起看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* 打印从 (start, start) 与 (endX, endY) 围成的一圈矩形
* @param {Array} arr
* @param {Number} cols
* @param {Number} rows
* @param {Number} start
*/
function printMatrixInCircle(arr, cols, rows, start) {
let endX = cols - start - 1,
endY = rows - start - 1,
result = ''

// 从 左上 到 右上 打印一行
for (let i = start; i <= endX; ++i) {
result = result + ' ' + arr[start][i]
}

// 从 右上 到 右下 打印一行
if (start < endY) {
for (let i = start + 1; i <= endY; ++i) {
result = result + ' ' + arr[i][endX]
}
}

// 从 右下 到 左下 打印一行
if (start < endX && start < endY) {
for (let i = endX - 1; i >= start; --i) {
result = result + ' ' + arr[endY][i]
}
}

// 从 左下 到 左上 打印一行
if (start < endX && start < endY - 1) {
for (let i = endY - 1; i >= start + 1; --i) {
result = result + ' ' + arr[i][start]
}
}

console.log(result)
}

/**
* 打印的外层函数, 主要用于控制要打印的圈
* @param {Array} arr
*/
function printMatrix(arr) {
if (!Array.isArray(arr) || !Array.isArray(arr[0])) {
return
}

let start = 0,
cols = arr[0].length,
rows = arr.length

while (cols > start * 2 && rows > start * 2) {
console.log(`第${start + 1}层: `)
printMatrixInCircle(arr, cols, rows, start)
++start
}
}

/**
* 以下是测试代码
*/

printMatrix([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
])

printMatrix([
[1, 2, 3, 4],
[4, 5, 6, 7],
[8, 9, 10, 11],
])