个人评价:二维数组,个人只想到了暴力方式 😂 且效率略差,等过一阵儿再来思考看看

题目难度:🌟🌟 (参考 LeeCode 简单🌟 、中等🌟 🌟 、困难🌟 🌟 🌟 )

另,通常算法题会考察分析时间复杂度和空间复杂度,可参考笔者之前的文章

「数据结构&算法」必知必会系列:3. 时间 & 空间复杂度(下)

顺时针打印矩阵(螺旋矩阵)

题目描述

剑指 Offer 29. 顺时针打印矩阵

54. 螺旋矩阵

给你一个 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

解题思路

个人没想到啥更好地方式,就暴力解了 😂 找规律,思路如下:

  • 分别有四种方式,→ ↓ ← ↑ 每个方向加入的元素满足一定的限制
  • 遍历次数取决于 m、n 中较小的那个数(如 [[1,2,3,4,5, …,m], [2,3,4,5,6,3, …., m]] 其实只需要 1 次,即使 m很大 )

Go 实现代码如下:

func spiralOrder(matrix [][]int) []int {
    if len(matrix)==0 {
        return []int{}
    }
    lenX := len(matrix[0])
    lenY := len(matrix)
    list := []int{}
    numLoop := 2*lenX
    if lenY<lenX {
        numLoop = 2*lenY
    }
    for n:=0; n<numLoop; n++ {
        fmt.Println(n)
        if n%4 == 0 { // →
            list = append(list, matrix[n/4][n/4:lenX-n/4]...)
            fmt.Println(list)
        }
        if n%4 == 1 { // ↓
            for i:=(n-1)/4+1; i< lenY-(n-1)/4; i++ {
                list = append(list, matrix[i][lenX-(n-1)/4-1])
            }
            fmt.Println(list)
        }
        if n%4 == 2 { // ←
            for j:=lenX-(n-2)/4-2; j>=(n-2)/4; j-- {
                list = append(list, matrix[lenY-(n-2)/4-1][j])
            }
            fmt.Println(list)
        }
        if n%4 == 3 { // ↑
            for i:=lenY-(n-3)/4-2; i>(n-3)/4; i-- {
                list = append(list, matrix[i][(n-3)/4])
            }
            fmt.Println(list)
        }
    }
    return list
}

边界条件还是有点略搞的 😓

复杂度?🙌 时间 O(mn) 空间 O(1) 除了输出数组以外,空间复杂度是常数。

总结

反而花了更多的时间看题解系列 😂 结果也没找到比暴力法更好的方式嘛

就这样吧,也许哪天突然想到回头过来 👀