59.螺旋矩阵II

  1. 59.螺旋矩阵II
    1. 59.1 题目
    2. 59.2 题解
      1. 方法一:逐层模拟
        1. 思路
        2. 复杂度分析
        3. 代码
    3. 59.3 代码
    4. 59.4 运行结果

59.螺旋矩阵II


59.1 题目

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

示例 1:

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

示例 2:

输入:n = 1
输出:[[1]]

提示:

  • 1 <= n <= 20

59.2 题解

方法一:逐层模拟

思路

与第54题类似,用四个边界指针 topbottomleftright 标记当前填充范围。按顺时针方向依次填充:从左到右、从上到下、从右到左、从下到上。每填充完一层,边界向内收缩,直到填满所有元素。用变量 nowVal 记录当前要填充的数字,从1递增到

核心思想:四边界逐层填充,顺时针方向。

具体步骤

  1. 创建 n × n 矩阵,初始化边界指针。
  2. top <= bottom && left <= right 时:
    • 从左到右填充上边界
    • 从上到下填充右边界
    • 从右到左填充下边界(需检查 top < bottom
    • 从下到上填充左边界(需检查 left < right
  3. 收缩边界,继续下一层。

举例:对于 n = 3

  • 第一层:上 [1,2,3],右 [4,5],下 [6,7],左 [8]
  • 第二层:中心 [9]
  • 结果:[[1,2,3],[8,9,4],[7,6,5]]

复杂度分析

  • 时间复杂度:O(n²),需要填充 个元素。
  • 空间复杂度:O(1),除结果矩阵外只使用常数空间。

代码

// 方法一:逐层模拟
// 大致思路和54题一致
// 区别是要创建一个要返回的nxn交错数组,设置行列都为n
// 定义索引用于填充交错数组
static int[][] GenerateMatrix1(int n)
{
    // 如果 n 为 1,直接返回一个包含 1 的二维数组
    if (n == 1)
    {
        return new int[][] { new[] { 1 } };
    }

    // 创建一个 n x n 的二维数组
    int[][] resultMatrix = new int[n][];

    // 初始化二维数组的每一行
    for (int i = 0; i < n; i++)
    {
        resultMatrix[i] = new int[n];
    }

    // 初始化四个边界指针,表示当前螺旋填充的上、下、左、右边界
    int top = 0;
    int left = 0;
    int right = n - 1;
    int bottom = n - 1;

    // 初始化当前要填充的数字
    int nowVal = 1;

    // 当上边界小于等于下边界且左边界小于等于右边界时,继续填充
    while (top <= bottom && left <= right)
    {
        // 从左到右填充当前行
        for (int i = left; i <= right; i++)
        {
            resultMatrix[top][i] = nowVal++;
        }

        // 从上到下填充当前列
        for (int i = top + 1; i <= bottom; i++)
        {
            resultMatrix[i][right] = nowVal++;
        }

        // 检查是否有足够的行和列使得可以从右到左填充
        if (left < right && top < bottom)
        {
            // 从右到左填充当前行
            for (int i = right - 1; i >= left; i--)
            {
                resultMatrix[bottom][i] = nowVal++;
            }

            // 从下到上填充当前列
            for (int i = bottom - 1; i > top; i--)
            {
                resultMatrix[i][left] = nowVal++;
            }
        }

        // 更新边界指示器,缩小螺旋填充范围
        top++;
        left++;
        bottom--;
        right--;
    }

    // 返回生成的二维数组
    return resultMatrix;
}

59.3 代码

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        #region 题目

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

        // 示例 1:
        // 输入:n = 3
        // 输出:[[1,2,3],[8,9,4],[7,6,5]]

        // 示例 2:
        // 输入:n = 1
        // 输出:[[1]]

        #endregion

        #region 测试

        // 示例 1
        int n1 = 3;
        int[][] resultMatrix1 = GenerateMatrix1(n1);
        Console.WriteLine($"示例1 方法1 输出:");
        PrintMatrix(resultMatrix1);

        // 示例 2
        int n2 = 1;
        int[][] resultMatrix2 = GenerateMatrix1(n2);
        Console.WriteLine($"示例2 方法1 输出:");
        PrintMatrix(resultMatrix2);

        #endregion
    }

    #region 答案

    // 方法一:逐层模拟
    // 大致思路和54题一致
    // 区别是要创建一个要返回的nxn交错数组,设置行列都为n
    // 定义索引用于填充交错数组
    static int[][] GenerateMatrix1(int n)
    {
        // 如果 n 为 1,直接返回一个包含 1 的二维数组
        if (n == 1)
        {
            return new int[][] { new[] { 1 } };
        }

        // 创建一个 n x n 的二维数组
        int[][] resultMatrix = new int[n][];

        // 初始化二维数组的每一行
        for (int i = 0; i < n; i++)
        {
            resultMatrix[i] = new int[n];
        }

        // 初始化四个边界指针,表示当前螺旋填充的上、下、左、右边界
        int top = 0;
        int left = 0;
        int right = n - 1;
        int bottom = n - 1;

        // 初始化当前要填充的数字
        int nowVal = 1;

        // 当上边界小于等于下边界且左边界小于等于右边界时,继续填充
        while (top <= bottom && left <= right)
        {
            // 从左到右填充当前行
            for (int i = left; i <= right; i++)
            {
                resultMatrix[top][i] = nowVal++;
            }

            // 从上到下填充当前列
            for (int i = top + 1; i <= bottom; i++)
            {
                resultMatrix[i][right] = nowVal++;
            }

            // 检查是否有足够的行和列使得可以从右到左填充
            if (left < right && top < bottom)
            {
                // 从右到左填充当前行
                for (int i = right - 1; i >= left; i--)
                {
                    resultMatrix[bottom][i] = nowVal++;
                }

                // 从下到上填充当前列
                for (int i = bottom - 1; i > top; i--)
                {
                    resultMatrix[i][left] = nowVal++;
                }
            }

            // 更新边界指示器,缩小螺旋填充范围
            top++;
            left++;
            bottom--;
            right--;
        }

        // 返回生成的二维数组
        return resultMatrix;
    }

    #endregion

    #region 辅助函数

    // 打印矩阵
    static void PrintMatrix(int[][] matrix)
    {
        foreach (var row in matrix)
        {
            Console.Write("[");
            // 使用 Join 方法将每个数字连接起来,逗号分隔
            Console.Write(string.Join(", ", row));
            Console.WriteLine("]");
        }
    }

    #endregion
}

59.4 运行结果

示例1 方法1 输出:
[1, 2, 3]
[8, 9, 4]
[7, 6, 5]
示例2 方法1 输出:
[1]


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏