数组 - 螺旋矩阵2

74 阅读3分钟

数组 - 螺旋矩阵2

本题以力扣上的59号题目为例。

image.png 这道题,卡哥说没有涉及什么算法,重点就是要把握好边界。我们尽量要将边界设计成统一的,不然的话每条边都一个规则容易把自己绕进去。

接下来就讲讲边界的规则:左闭右开

image.png 这里说的边界规则是,每次循环我们如何填充数据 - 每条边上的数据我们只填起始位置到终止位置的前一个元素。比如上图:上面这条边有[1,2,3,4]四个数,我们只填充[1,2,3]这三个数,[4]我们作为右面这条边的起始位置。这样我们就统一了填充规则。

上图每个数我都编好了下标,接下来我们就对着编号进行填充数据即可,注意是从上右下左的顺序。

还有一个比较重要的点就是:我们如何控制旋转的圈数。比如给一个4,我们如何控制旋转几圈?如果不知道,我们就举例子

数字圈数
11
21
32
42
53

上面我是根据自己画图距离得出的结果,不过还是得注意,当n是奇数的时候如何填充数据。根据卡哥的讲解,如果是奇数,我们在循环外面填充。

image.png 以3为例,我们循环就只转一圈,中间的9我们在循环外填充

具体代码如下

// 1    2   3   4
// 12   13  14  5
// 11   16  15  6
// 10   9   8   7

func generateMatrix(n int) [][]int {
    // 初始化结果对象
    res := make([][]int, n)
    for t := 0; t < n; t++{
        res[t] = make([]int, n)
    }

    x, y := 0, 0 // 起始坐标位置
    offset := 1 // 偏移量,因为圈是不断缩小的,每次都需要缩小1
    num := 1
    for p := 0; p <= n / 2 ; p++{
        // 完成上部那条边
        i, j := x, y // i, j就是需要变动的指针
        for ; j < n - offset; j++ {
            res[x][j] = num
            num++
        }
        // 完成右部那条边
        for ; i < n - offset; i++{
            res[i][j] = num
            num++
        }
        // 完成下部那条边
        for ; j > x; j--{
            res[i][j] = num
            num++
        }
        // 完成左部那条边
        for ; i > y; i--{
            res[i][y] = num
            num++
        }
        x++
        y++
        offset++
        // if p % 2 == 1 {
        //     res[i][j] = num
        // }
    }
    // 手动填充中间的数据
    if n % 2 == 1 {
        res[n/2][n/2] = n*n
    }
    fmt.Println(res)
    return res
}

上述是力扣中的题目,下面给一个今年多抓鱼我遇到的一个算法题,和这个类似。原题大概描述一下

image.png 大家看这个图应该能知道,给定一个n,拼凑成一个等腰直角三角形,且左上角是直角。具体的思路和卡哥讲得差不多

func generateSanJiao(n int) [][]int {
    // 初始化结果
    res := make([][]int, n)
    for t := 0; t < n; t++ {
        res[t] = make([]int, n-t)
    }
    x, y := 0, 0
    num := 1
    offset := 1
    for p := 0; p < n/2; p++ {
        i, j := x, y
        // 左
        for ; i < n-offset-p; i++ {
            res[i][y] = num
            num++
        }
        // 侧
        for ; i >= offset && j < n-offset-p; i, j = i-1, j+1 {
            res[i][j] = num
            num++
        }
        // 上
        for ; j >= offset; j-- {
            res[x][j] = num
            num++
        }
        if n%2 == 0 {
            res[i][j] = num
        }
        x++
        y++
        offset++
    }

    fmt.Println(res)
    return res
}