螺旋矩阵

学习文本来源:代码随想录

力扣地址

给定一个正整数n,生成一个包含1到n^2所有元素,且元素按顺时针螺旋排列的长方形矩阵

示例:

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

思路

这道题可以说在面试中出现频率较高的题目本题不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。

如何画出这个螺旋排列的矩阵呢?

相信很多同学刚开始做这种题目的时候,上来就是一波判断猛如虎。

结果运行的时候各种问题,然后开始各种修修补补,最后发现改这里那里有问题,改了那里这里又有问题。

二分法提到了循环变量不遍量原则。

本题依然要坚持循环变量不变原则。

模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

右外向内一圈这么画下去。

可以发现这里边界条件很多,在一个循环中,如此多边界条件,如果不按照固定规律来遍历,那么就是一进循环深似海,从此offer是路人。

这里一圈下来,我们要花四条边,这四条边怎么画,每一条边都要坚持一致的左闭右开,或者左闭右闭,这样一圈才能按照统一的规划画下来。

那么我们按照左闭右闭的原则来画一圈,大家看一下

这里每一种颜色,代表一条边,我们遍历的长度,可以看出每一个拐角的处理规则,拐角处让新的一条边来继续画。

这也是坚持了每条边左闭右开的原则。

一些同学这道题目之所以一直写不好,代码越写越乱。

就是因为在画每一条边的时候一会左闭右开,一会左闭右闭,怎么会不乱。

代码如下:
golang:

func generateMatrix(n int) [][]int {
    res := make([][]int, n)
    for i := 0; i < n; i++ {
        res[i] = make([]int, n)
    }
    // 定义每循环一个圈的起始位置
    startX, startY := 0, 0
    // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
    var loop int = n / 2
    // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
    var mid int = n / 2
    // 用来给矩阵中每一个空格赋值
    var count int = 1
    // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
    var offset int = 1

    for loop > 0 {
        //i 横向
        x, y := startX, startY

        //左到右
        for y = startY; y < n-offset; y++ {
            res[x][y] = count
            count++
        }

        //上到下
        for x = startX; x < n-offset; x++ {
            res[x][y] = count
            count++
        }

        //右到左
        for y > startY {
            res[x][y] = count
            count++
            y--
        }

        //下到上
        for x > startX {
            res[x][y] = count
            count++
            x--
        }

        loop--
        offset++
        startX++
        startY++
    }

    if n%2 == 1 {
        res[mid][mid] = count
    }

    return res
}
Last modification:May 28, 2024
如果觉得我的文章对你有用,请收藏本站