• leetcode(力扣) 59. 螺旋矩阵 II (边界控制思路)


    题目描述

    给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

    示例 1:在这里插入图片描述
    输入:n = 3
    输出:[[1,2,3],[8,9,4],[7,6,5]]

    简化题目

    生成一个n*n的矩阵,矩阵内的数字按照顺时针的方式填充,从1开始。

    思路分析

    这道题刚拿到手没什么比较好的思路,直接暴力循环,然后做了一小时没过去,边界处理实在繁琐,总是各种出错。

    在这里插入图片描述

    整理思路,按照每一圈四条边的逻辑来处理,也就是 顺时针一圈的四条边,按照顺序 上右下左 四条边。

    首先理清一条边的思路,在一条边中,我们处理包含第一个数,但不包含最后一个数,最后一个数由下一条边去处理,这里看图就很容易理解了,所以处理每一条边的区间是[x,y)。

    当到达第二圈的时候还有几个需要注意的地方,按下面这个例子,第一圈循环完之后,将开始循环内圈,从5开始,5,6,10,9这样的顺序。这里一定要想清楚,我们开始定义的区间是[x,y),所以内圈的循环,上边的边负责5,右边的负责6,下边的负责10,左边的负责9。
    其实可以发现 第一圈开始点为(0,0) 第二圈开始点为(1,1)所以我们要设置一个变量控制每一圈的起始点,start_x = 0 和start_y=0。

    在这里插入图片描述

    再进一步的,每一条边的结束位置也需要调整,在上面的例子中可以看到,按照一开始的[x,y)区间循环每一条边,在第一圈的时候,每一条边终止点为第一行的倒数第一个(不包含),而进入内圈之后,每一条边的 终止点为倒数第二个(不包含),所以这里还要定义一个变量temp=1.没经过一圈就加1,用来控制每条边的结束位置。

    最后就是循环多少圈了,这个比较好想 n//2圈就行了。

    完整代码

    # 每一个循环处理区间  [x,y)
    
            start_x = 0
            start_y = 0
            temp = 1
            count = 1
            res = [[0] * n for _ in range(n)]
            for _ in range(n // 2):
                # 处理最上面一行
                for y in range(start_y, n - temp):
                    res[start_x][y] = count
                    count += 1
                # 处理最右边一列
                for x in range(start_x, n - temp):
                    res[x][n - temp] = count
                    count += 1
                # 处理最下边一行
                for y in range(n - temp, start_y, -1):
                    res[n - temp][y] = count
                    count += 1
                # 处理最左边一列
                for x in range(n - temp, start_x, -1):
                    res[x][start_y] = count
                    count += 1
                temp += 1
                start_x += 1
                start_y += 1
    
            if n % 2 != 0:
                res[n // 2][n // 2] = count
            return res
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    时隔两个多月又刷到这个题。优化了一下思路。

    放上二刷代码。

    start_index = 0
    count = 1
    #左闭右开  包含左边 不包含右边
    
    res = [[0] * n for _ in range(n) ]
    
    num =  n // 2 # 需要遍历的圈数 奇数的话中间需要加一个数字
    for temp in range(1,num+1):
        # 遍历最上边一行
        for i in range(start_index,n-temp):
            res[start_index][i] = count
            count +=1
        # 遍历最右边一行
        for i in range(start_index,n-temp):
            res[i][n-temp] = count
            count+=1
        # 遍历最下边一行
        for i in range(n-temp,start_index,-1):
            res[n-temp][i] = count
            count+=1
        # 遍历最左边一行
        for i in range(n-temp,start_index,-1):
            res[i][start_index] = count
            count+=1
        start_index +=1
    if n % 2 !=0:
        res[n//2][n//2] = count
    print(res)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    可以看到二刷并没有用之前一刷的时候定义的star_x和star_y这两个变量。

    因为不管是行还是列,起始点和结束点都可以通过其他的变量来控制。

    起始点和终点都可以由 for temp in range(1,num+1): 里的 temp
    结合 start_index , temp-n 这两个变量来控制起始点和终点。代码和思路更清晰了。

  • 相关阅读:
    Markdown语法
    青少年软件编程C++二级题库(21-30)
    LeetCode刷题(python版)——Topic51N 皇后
    Python入门(二十四)-文件操作2
    C++ STL之string类模拟实现
    PySpark数据分析基础:pyspark.sql.SparkSession类方法详解及操作+代码展示
    写代码中碰到的错误
    hive数据库将非分区表数据迁移到分区表
    Bootstrap Blazor 实战 Menu 导航菜单使用(1)
    odoo--qweb模板介绍(一)
  • 原文地址:https://blog.csdn.net/qq_38737428/article/details/126905087