美文网首页工作生活
Leetcode【54、59、885】

Leetcode【54、59、885】

作者: 牛奶芝麻 | 来源:发表于2019-07-02 20:39 被阅读0次
    问题描述:【Array】54. Spiral Matrix
    解题思路:

    这道题是给一个矩阵,按顺时针螺旋输出所有数字。

    这道题做法很直接,就是从最外层到最内层一层一层按照顺时针螺旋输出各个数字即可。如下图所示:


    用 (i, j) 表示矩阵坐标,k 表示层数。对于每一层,我们从左到右(橙色)、从上到底(红色)、从底到左(绿色)、从左到上(蓝色)依次输出。然后,层数加 1,进入下一层继续循环输出。直到输出所有数字。

    编程时,注意找到 i、j 下标及层数 k 的对应关系。例如从左到右(橙色)的判断条件是 if i == k and j != n - 1- k:(初始化 i = j = k = 0)。

    Python3 实现:
    class Solution:
        def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
            if not matrix:
                return []
            m, n = len(matrix), len(matrix[0])
            i = j = k = 0  # (i,j)表示坐标, k表示层数
            ans = []
            while True:
                if i == k and j != n - 1 - k:  # 从左到右
                    ans.append(matrix[i][j])
                    j += 1
                elif i != m - 1 - k and j == n - 1 - k:  # 从右到底
                    ans.append(matrix[i][j])
                    i += 1
                elif i == m - 1 - k and j != k:  # 从底到左
                    ans.append(matrix[i][j])
                    j -= 1
                elif i != k and j == k:  # 从左到上
                    ans.append(matrix[i][j])
                    i -= 1
                    if i == k:  # 遍历完一层,进入下一层
                        i += 1
                        j += 1
                        k += 1
                else:  # 方阵情况(m=n),最后输出最中心的数字
                    ans.append(matrix[i][j])
                if len(ans) == m * n: # 达到长度,返回结果
                    return ans
    

    问题描述:【Array】59. Spiral Matrix II
    解题思路:

    这道题是给一个数字 n,按顺时针螺旋顺序将 1~n^2 保存到 n*n 矩阵中。

    思路同上面的 Leetcode 54。

    Python3 实现:
    class Solution:
        def generateMatrix(self, n: int) -> List[List[int]]:
            matrix = [[0] * n for _ in range(n)]
            cnt = 1
            i = j = k = 0  # (i,j)表示坐标, k表示层数
            while cnt <= n * n:
                if i == k and j != n - 1 - k:  # 从左到右
                    matrix[i][j] = cnt; cnt += 1
                    j += 1
                elif i != n - 1 - k and j == n - 1 - k:  # 从右到底
                    matrix[i][j] = cnt; cnt += 1
                    i += 1
                elif i == n - 1 - k and j != k:  # 从底到左
                    matrix[i][j] = cnt; cnt += 1
                    j -= 1
                elif i != k and j == k:  # 从左到上
                    matrix[i][j] = cnt; cnt += 1
                    i -= 1
                    if i == k:  # 遍历完一层,进入下一层
                        i += 1; j += 1; k += 1
                else:  # 最后填充最中心的数字
                    matrix[i][j] = cnt; cnt += 1
            return matrix
    

    题目描述:【Array】885. Spiral Matrix III
    解题思路:

    这道题是在 R 行 C 列的矩阵上,从 (r0, c0) 面朝东面开始按顺时针按螺旋状行走,访问此网格中的每个位置。每当移动到网格的边界之外时,会继续在网格之外行走(但稍后可能会返回到网格边界)。最终,到过网格的所有 R * C 个空间,按照访问顺序返回表示网格位置的坐标列表。

    这道题的关键是要知道每次要朝一个方向走几步或者什么时候转向。以示例 2 为例:

    可以观察到,由 1 到 2、2 到 3 各走一步;由 3 到 5、5 到 7 各走两步;.... 因此可以发现,每两次转向,步数加 1。

    编程时,我们用一个变量 tour 控制四个方向 (使用 tour % 4 实现),每次转向 tour += 1;用 step 表示一个方向走 step 步才转向;用 cnt 表示转向的次数,每转两次向让 step += 1。因此,我们很容易写出代码。注意,可能走出网格,网格之外的坐标不加入到最后的结果中就行。

    Python3 实现:
    class Solution:
        def spiralMatrixIII(self, R: int, C: int, r0: int, c0: int) -> List[List[int]]:
            ans = []
            i, j = r0, c0  # (i,j)表示坐标位置
            ans.append([i, j])
            step = cnt = tour = 0  # step表示朝一个方向走step步, cnt表示转向次数, tour表示走完step步改变一次方向
            
            while len(ans) < R * C:
                
                if cnt % 2 == 0:  # 两次转向后对step值加1
                    step += 1
                tmp = step
                    
                while tmp != 0 and tour % 4 == 0:  # 向东
                    tmp -= 1
                    j += 1
                    if 0 <= i < R and 0 <= j < C:  # 坐标不能越界
                        ans.append([i, j])
                while tmp != 0 and tour % 4 == 1:  # 向南
                    tmp -= 1
                    i += 1
                    if 0 <= i < R and 0 <= j < C:
                        ans.append([i, j])
                while tmp != 0 and tour % 4 == 2:  # 向西
                    tmp -= 1
                    j -= 1
                    if 0 <= i < R and 0 <= j < C:
                        ans.append([i, j])
                while tmp != 0 and tour % 4 == 3:  # 向北
                    tmp -= 1
                    i -= 1
                    if 0 <= i < R and 0 <= j < C:
                        ans.append([i, j])
            
                tour += 1  # 走完step步改变一次方向
                cnt += 1  # 转向次数加1
    
            return ans
    

    相关文章

      网友评论

        本文标题:Leetcode【54、59、885】

        本文链接:https://www.haomeiwen.com/subject/hjagcctx.html