分析:我看过很多答案都百思不得其解,今天参考了大神答案才解决。这道题我们不能把他复杂化,不需要写很多变量如top、bottom之类的,反正我看一下就晕了,回归最简单的写法。
(1)首先有个最重要的点,本题要求的返回值是交错数组,不是二维数组!
那交错数组是什么?和二维数组区别在哪里?
交错数组就是数组的数组,它和二维数组的区别在于,二维数组[,]每行的列数相同,而交错数组[][]每行的列数可能不同,它只能初始化行数,不能初始化列数
(2)边界问题,那每一个数组我还是习惯用左闭右开。比如第一行,左闭右开是1、2 不包括元素3的,也就是再下次循环中是从3开始的,所以下次循环3、4不包括5的
(3)圈数问题,需要转几圈呢?答案是 n/2。直接画出n = 2 - 5之间的矩阵,很明显能观察出,当n是偶数时,圈数n/2;n是奇数时,我们可以单独处理最后一个元素即可(不用太过纠结细枝末节的问题 只要能想通问题的方法都是好方法)
(4)变量问题,只需要两个变量作为标识即可,因为我们要的答案无非就是便利每一行每一列,只要遵循这个原则,不难写出strat = 0,end = n - 1,不需要写那么多变量
public class Solution {
public int[][] GenerateMatrix(int n) {
//首先创建矩阵 也就是交错数组 只能写行数不能写列数哦
int[][] answer = new int[n][];
for(int i =0; i < n; i++)
{
answer[i] = new int[n];
}
int start = 0;
int end = n-1;
//count就是我们需要填充的元素 从1开始即可
int count = 1;
//当count小于矩阵最中心的元素 我们就进入循环
//在循环外会单独处理中心元素
while(count < n*n)
{
//假设n = 3 代入更好理解
//[{1, 2, 3}
// {4, 5, 6}
// {7, 8, 9}]
// 向右 行不变列变 [1, 2]
for(int i = start; i < end; i++)
{
//第一次遍历是最好理解的 记得遵循左闭右开原则
answer[start][i] = count++;
}
//向下 行变列不变 [3, 4]
for(int i = start; i < end; i++)
{
//第二次遍历 其实就是单纯的start作为起始值 end作为终点值
//行变那列不变 那行肯定就是i 列自然就是最大值end
//我们变化的元素最终只有count
answer[i][end] = count++;
}
//向左 行不变列变 [5, 6]
for(int i = end; i > start; i--)
{
//第三次遍历 该往左边走了 就是end > start
//行不变列变 那列就是i 行就是最大值end
answer[end][i] = count++;
}
//向上 行变列不变 [7, 8]
for(int i = end; i > start; i--)
{
//第四次遍历 该往上走元素就两个呀 怎么写法一模一样?
//其实每次遍历的元素都只有两个 我们是遵循左闭右开原则
//所以这里也是两个元素 没有越界
answer[i][start] = count++;
}
//一圈之后 start++ end-- 也很好理解
//圈变小了 起始值变大和终点值变小
start++;
end--;
}
//如果是奇数 单独处理中间的元素即可
if(n%2 == 1) answer[n/2][n/2] = count;
return answer;
}
}