螺旋矩阵
- https://leetcode.cn/problems/spiral-matrix/
描述
- 给你一个 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
Typescript 版算法实现
1 )减而治之递归实现
function spiralOrder(matrix: number[][]): number[] {
// 处理每一圈的数据遍历过程
const map = (arr: number[][], r: number[] = []) => {
// 第一圈的遍历:遍历的时候不会按照 if else if 的顺序遍历,而是会按照一行一行的遍历,所以最终顺序不用担心
for (let i = 0, len = arr.length; i < len; i++) {
if (i === 0) {
r = r.concat(arr[i])
} else if (i === len - 1) {
r = r.concat(arr[i].reverse())
} else {
// 增加边界检查
if (arr[i].length) {
r.push(arr[i].pop())
}
}
}
arr.shift() // 减而治之:移除第一行
arr.pop() // 减而治之:移除最后一行
// 第一圈最后的遍历: 倒序,从下到上
for (let i = arr.length - 1; i >= 0; i--) {
// 边界检查
if (arr[i].length) {
r.push(arr[i].shift())
}
}
// 边界判断,是否还有,有则进行递归
if (arr.length) {
return map(arr, r)
}
// 没有直接返回
return r;
}
return map(matrix, [])
};
- 没办法一次性一圈圈的描述出来,但是可以把一圈的过程描述出来
- 描述一圈经历了几件事: 顺时针
- 二维矩阵第一行 (从做到右)
- 二维矩阵最后一列 (从上到下)
- 二维矩阵倒数第一行 (从右到左)
- 二维矩阵第一列 (从下到上)
- 整体算法
- 先遍历第一圈,减而治之
- 如果还有,则递归实现
Python3 版算法实现
1 )方案1:减而治之递归实现
from typing import List
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
def map_func(arr: List[List[int]], r: List[int] = []) -> List[int]:
if not arr:
return r
# 处理第一行
r.extend(arr[0])
# 移除第一行
arr = arr[1:]
if not arr:
return r
# 处理最后一列
for i in range(len(arr)):
if arr[i]:
r.append(arr[i].pop())
# 移除最后一行
if arr and arr[-1]:
r.extend(arr.pop()[::-1])
# 处理第一列
for i in range(len(arr) - 1, -1, -1):
if arr[i]:
r.append(arr[i].pop(0))
# 递归处理剩余的部分
return map_func(arr, r)
return map_func(matrix)
Golang 版算法实现
1 )方案1:减而治之递归实现
func spiralOrder(matrix [][]int) []int {
return mapFunc(matrix, []int{})
}
func mapFunc(arr [][]int, r []int) []int {
if len(arr) == 0 {
return r
}
// 处理第一行
r = append(r, arr[0]...)
// 移除第一行
arr = arr[1:]
if len(arr) == 0 {
return r
}
// 处理最后一列
for i := 0; i < len(arr); i++ {
if len(arr[i]) > 0 {
r = append(r, arr[i][len(arr[i])-1])
arr[i] = arr[i][:len(arr[i])-1]
}
}
// 处理最后一行
if len(arr) > 0 && len(arr[len(arr)-1]) > 0 {
r = append(r, reverse(arr[len(arr)-1])...)
}
// 移除最后一行
arr = arr[:len(arr)-1]
if len(arr) == 0 {
return r
}
// 处理第一列
for i := len(arr) - 1; i >= 0; i-- {
if len(arr[i]) > 0 {
r = append(r, arr[i][0])
arr[i] = arr[i][1:]
}
}
// 递归处理剩余的部分
return mapFunc(arr, r)
}
func reverse(arr []int) []int {
for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
arr[i], arr[j] = arr[j], arr[i]
}
return arr
}
2065



被折叠的 条评论
为什么被折叠?



