# [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) ## 题目 Given a matrix of *m* x *n* elements (*m* rows, *n* columns), return all elements of the matrix in spiral order. **Example 1**: Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,3,6,9,8,7,4,5] **Example 2**: Input: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] Output: [1,2,3,4,8,12,11,10,9,5,6,7] ## 题目大意 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 ## 解题思路 - 给出一个二维数组,按照螺旋的方式输出 - 解法一:需要注意的是特殊情况,比如二维数组退化成一维或者一列或者一个元素。注意了这些情况,基本就可以一次通过了。 - 解法二:提前算出一共多少个元素,一圈一圈地遍历矩阵,停止条件就是遍历了所有元素(count == sum) ## 代码 ```go package leetcode // 解法 1 func spiralOrder(matrix [][]int) []int { if len(matrix) == 0 { return []int{} } res := []int{} if len(matrix) == 1 { for i := 0; i < len(matrix[0]); i++ { res = append(res, matrix[0][i]) } return res } if len(matrix[0]) == 1 { for i := 0; i < len(matrix); i++ { res = append(res, matrix[i][0]) } return res } visit, m, n, round, x, y, spDir := make([][]int, len(matrix)), len(matrix), len(matrix[0]), 0, 0, 0, [][]int{ []int{0, 1}, // 朝右 []int{1, 0}, // 朝下 []int{0, -1}, // 朝左 []int{-1, 0}, // 朝上 } for i := 0; i < m; i++ { visit[i] = make([]int, n) } visit[x][y] = 1 res = append(res, matrix[x][y]) for i := 0; i < m*n; i++ { x += spDir[round%4][0] y += spDir[round%4][1] if (x == 0 && y == n-1) || (x == m-1 && y == n-1) || (y == 0 && x == m-1) { round++ } if x > m-1 || y > n-1 || x < 0 || y < 0 { return res } if visit[x][y] == 0 { visit[x][y] = 1 res = append(res, matrix[x][y]) } switch round % 4 { case 0: if y+1 <= n-1 && visit[x][y+1] == 1 { round++ continue } case 1: if x+1 <= m-1 && visit[x+1][y] == 1 { round++ continue } case 2: if y-1 >= 0 && visit[x][y-1] == 1 { round++ continue } case 3: if x-1 >= 0 && visit[x-1][y] == 1 { round++ continue } } } return res } // 解法 2 func spiralOrder2(matrix [][]int) []int { m := len(matrix) if m == 0 { return nil } n := len(matrix[0]) if n == 0 { return nil } // top、left、right、bottom 分别是剩余区域的上、左、右、下的下标 top, left, bottom, right := 0, 0, m-1, n-1 count, sum := 0, m*n res := []int{} // 外层循环每次遍历一圈 for count < sum { i, j := top, left for j <= right && count < sum { res = append(res, matrix[i][j]) count++ j++ } i, j = top + 1, right for i <= bottom && count < sum { res = append(res, matrix[i][j]) count++ i++ } i, j = bottom, right - 1 for j >= left && count < sum { res = append(res, matrix[i][j]) count++ j-- } i, j = bottom - 1, left for i > top && count < sum { res = append(res, matrix[i][j]) count++ i-- } // 进入到下一层 top, left, bottom, right = top+1, left+1, bottom-1, right-1 } return res } ```