54. 螺旋矩阵

https://leetcode.cn/problems/spiral-matrix/description/

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100

解题思路

走一圈,去个壳,继续走

代码


func spiralOrder(matrix [][]int) []int {
	var res []int
	for len(matrix) > 0 {
		var i, j int
		move := right
		for move != 0 {
			res = append(res, matrix[i][j])
			move = next(matrix, i, j, move)
			switch move {
			case right:
				j++
			case down:
				i++
			case left:
				j--
			case up:
				i--
			}
		}
		matrix = rebuild(matrix)
	}
	return res
}

const (
	right = 1
	down  = 2
	left  = 3
	up    = 4
)

// 判断下一步往哪儿走
func next(matrix [][]int, i, j int, move int) int {
	m := len(matrix)
	if m == 0 {
		return 0
	}
	n := len(matrix[0])
	switch move {
	case right:
		if j == n-1 {
			// 如果下一步无法往下走,终止
			if i == m-1 {
				return 0
			}
			return down
		}
	case down:
		if i == m-1 {
			// 如果下一步无法往左走,终止
			if j == 0 {
				return 0
			}
			return left
		}
	case left:
		if j == 0 {
			// 如果下一步无法往上走,终止。这里注意,是1不是0,因为0是起点
			if i == 1 {
				return 0
			}
			return up
		}
	case up: // 走完上就结束了
		if i == 1 {
			return 0
		}
	}
	return move
}

// 矩阵去壳
func rebuild(matrix [][]int) [][]int {
	if len(matrix) == 0 {
		return nil
	}
	if len(matrix) <= 2 || len(matrix[0]) <= 2 {
		return nil
	}
	var res [][]int
	for i := 1; i < len(matrix)-1; i++ {
		res = append(res, matrix[i][1:len(matrix[i])-1])
	}
	return res
}