一、问题描述
| Category | Difficulty | Likes | Dislikes |
|---|---|---|---|
| algorithms | Medium (77.37%) | 618 | - |
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20
二、xin麒的思路
1、摘要:
该题主要是涉及边界的问题,同时考察对编程的熟练程度(占比也不大),本题应用到作者的方法论有:观察法(通过观察得到规律)、特定代入法(使用几个典型的模型代入,构造出代入的模型的解决框架,再详细分析完善各种特殊的情况)
2、前提引入:
- 每次都将num变量赋值给遍历到的数组元素,并且每次num都会自增;
- 以
end = n和start = 0分别作两边界的初始化; - 第**(first + 1)行 第(second + 1)列的数组元素为nums[first][second]**;
3、分析:
通过观察,发现矩阵有三个转折点,分别为左上角,右下角,左下角,我们知道,那么状态改变时(进行转折)这三处很有可能会做出一些变化。我们可以取当n=3的情况进行分析:
- 3.1.1指针一直往左走:当在第一行遍历时,
second不断增加,直到second等于end - 1时,便达到临界状态,那么循环退出条件必然包括second < end;
- 停顿下思考 --> 需要将
second调整为end - 1,保持second在最后一列;同时我们希望下一次修改数组元素时是可以在下一个元素开始,于是需要将first + 1;
- 3.1.2指针一直往下走:first不断增加,当向下走到尽头时,便是first等于end-1时的临界状态,循环退出条件必然包括
first < end;
- 我们停顿下思考 --> 我们需要将
first保持为end - 1,同时我们希望下一次修改数组元素时是可以在下一个元素开始,于是需要将second - 1;另外考虑到如果再有1向下走的情况,那么end应该是需要减小了,于是需要end - 1;
- 3.1.3指针一直往左走,当向左时,
second不断减小,当减小到second等于start时,便到达临界状态。循环退出条件必然包括second >= start;
- 停顿下思考 --> 我们希望接下来可以向上转折,那么需要将
second保持为start;同时我们希望下一次修改数组元素时是可以在下一个元素开始,于是需要将first - 1;
- 因为向左走时,该层循环左边界start等于0,那么下次继续左走时,左边界应该向右收索,那么需要
start+1(也因为向上走时上边界是start+1,这样修改也符合);
-
3.1.4当一直向上走,当走到坐标(1,0)的位置,修改好元素时便退出,那么循环退出条件必然包括
first >= start; -
3.2此后外部循环继续,重新定义
first = start,second = start,也就是说每一次外层循环开始时都是从左上角到右下角的对角线对应的元素开始的,符合; -
3.3外层循环的退出条件的思考:我们可以看数组元素的不断修改的过程,如果数组的最后一个数被修改了,会是什么情况呢?是数组元素被值为n*n的num变量赋值了。但是由于num是一个不断增长的数,那么我们可以使用
num != n*n + 1来作为最外层的循环的循环条件
- 而内层有4个并行的循环,防止num为
n*n + 1时会进入这些内层循环,于是再在内层循环条件里并上一个和外层循环一样的条件。
三、xin麒的题解
class Solution {
public int[][] generateMatrix(int n) {
int num = 1;
int end = n;
int start = 0;
int[][] nums = new int[n][n];
int finalnum = n * n + 1;
int first = 0;
int second = 0;
while (num != finalnum){
first = start;
second = start;
while (second < end && num != finalnum){//往右
nums[first][second++] = num++;
}
second--;//上述循环second退出了边界,需要补回
first++;
while (first < end && num != finalnum){//往下
nums[first++][second] = num++;
}
first--;//上述循环first退出了边界,需要补回
second--;
end--;//这时右边界向左收缩
while (second >= start && num != finalnum){//往左
nums[first][second--] = num++;
}
second++;//上述循环second退出了边界,需要补回
start++;//左边界向右收缩
first--;
while (first >= start && num != finalnum){//往上
nums[first--][second] = num++;
}
}
return nums;
}
}
运行:


本文详细讲解如何利用观察法和特定代入法解决编程问题,以生成一个n×n的螺旋矩阵,重点在于理解转折点的处理和边界条件的调整。通过实例和步骤分析,展示了如何构造和维护矩阵的螺旋结构,适合算法初学者和进阶者参考。
197

被折叠的 条评论
为什么被折叠?



