1. 题目描述

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

2. 思路分析

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

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

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

3. 代码实现

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

/**
 * 打印从 (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]]);
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