题目描述
给你一个正整数 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
java解法:
首先题中要求1 <= n <= 20取值范围,使用双循环不会超时;分析题中要求,需要创建一个二维数组res,一个记录数组增长的count=1,一个用来记录开始位置的start。
1.首先的话是定义圈数,围成一圈的数的个数是一个偶数,所以可以通过n%2,来判断输入的数是奇数和偶数。因为偶数会刚好围成圈,而奇数最终会在圈中间多出一个中间值。所以需要一步操作来判断是否有中间值,那奇数的话怎么求这个中间值呢?可以通过简单枚举得出,当n=3时,中间数为res[1][1],当n=5时,中间值为res[2][2],可以分析出中间值索引为圈数,值为n*n;每一圈的不同起点是通过start来计算的。为[start][start],刚开始是[0][0],过了一圈后,start+1,第二圈从[1][1]开始,之后以此类推。
2.定义好圈数,一圈四条边,每天边可以好几种遍历方式,一条边是由n个数,这里我们分析的是每条边遍历n-1个数,如下图所示:
思路我们有了,下面我们看具体的代码实现:
java参考代码
class Solution { public int[][] generateMatrix(int n) { int [][] res =new int [n][n]; int num=1; int count =1; int start =0; int x,y; // n/2来确定圈数 while(num<=n/2){ //首先对上边界进行遍历 数组从0开始,当y=n-num时退出,刚好到右边界遍历开头 for(y=start;y<n-num;y++){ res[start][y] = count++; } //开始遍历右边界 数组从0开始,当x=n-num时退出,刚好到下边界遍历开头 for(x=start;x<n-num;x++){ res[x][y] =count++; } //此时x已经是n-num了,y是n-num,开始遍历下边界,只需要移动y即可,不需要再进行多余的遍历,保持y>=num ,结束之后y的值为0,刚好到达左边边界 for(;y>=num;y--){ res[x][y] = count++; } //此时 遍历左边界,y已经到达左边界了,只需要移动x就行,需要满足x>=num,循环结束后x=0,之后又重新赋值x了,x=0时的索引值并未写进数组所以没什么影响。 for(;x>=num;x--){ res[x][y] = count++; } //一圈已经结束了,开启下一圈,将圈的其实位置和圈数更新 start++; num++; } //海鸥如果是奇数的话,需要求中间值,写在循环外,此时num就是n*n,因为count是先执行后++的,所以count=n*n;此时圈数也知道了,进行判断 if(n%2 == 1){ res[start][start] = count; } return res; } }
go参考代码:
因为数组是动态的,所以在go中我们使用二维切片来进行记录索引和值
不同于java思路,在go中我们现规定了边界,,然后通过移动边界,来进行处理
func generateMatrix(n int) [][]int { top,bottom:=0,n-1 left,right:=0,n-1 num := 1 tar := n*n matrix := make([][]int,n) for i:=0;i<n;i++{ matrix[i] = make([]int,n) } for num <= tar{ for i:=left;i<=right;i++{ matrix[top][i] =num; num++; } top++ for i:=top;i<=bottom;i++{ matrix[i][right]=num; num++; } right-- for i:=right;i>=left;i--{ matrix[bottom][i] =num; num++; } bottom--; for i:=bottom;i>=top;i--{ matrix[i][left] =num; num++; } left++; } return matrix }
以上分析,希望对您有所帮助,您的支持是我最大的动力,感谢一键三连!!