螺旋矩阵问题
- 给你一个正整数n ,生成一个包含1到 n2 所有元素,且元素按顺时针顺序螺旋排列的n x n正方形矩阵matrix。
问题分析
当n=3是,是一个3x3正方形矩阵
整个生成过程就是从左到右,从上到下,从右到左,从下到上,采用循环分步操作就很容易实现。
但是需要注意很多问题:
(1)拐角问题
- 从图中可以看出有很多重合的地方,就是每一个拐角,想要处理好问题必须先解决拐角,也就是每一步的边界问题。
- 可采取每一到达拐角处就进入下一步,让下一步来处理这个拐角,比如从左到右是1到2,到3时就让从上到下那一步来处理。
整个处理过程为:
(2)存在中间数
- 当n为奇数时,需要单独处理中间的元素
本例子只进行了一圈的处理,如果当n>3,内层还会有同样的问题需要处理,这里的处理圈数为n/2。
边界的处理,最外层就是每一条边遍历n-1次,内层逐渐递减2次,且为左闭右开。
整体代码
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int startX=0,startY=0; //每一个圈的起始位置
int cycleNums=n/2; //一共循环几圈
int count=1; //用来给矩阵赋值
int control=1; //控制每一步即每一条边遍历的长度
int i,j;
while(cycleNums-->0){
//从左到右赋值
for(j=startY;j<startY+n-control;j++){
matrix[startX][j]=count++;
}
//从上到下
for(i=startX;i<startX+n-control;i++){
matrix[i][j]=count++;
}
//从右到左
for(;j>startY;j--){
matrix[i][j]=count++;
}
//从下到上
for(;i>startX;i--) {
matrix[i][j] = count++;
}
//起始位置加1
startX++;
startY++;
//控制每一圈每一条边遍历的长度,每一圈缩小的长度为2,所以加2
control+=2;
}
//如果n为奇数,则存在中间元素,单独给它赋值
if(n%2!=0){
matrix[n/2][n/2]=count;
}
return matrix;
}