Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.
Example:
Input: 3 Output: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
这一题我就用了一个很笨的方法。。emm
就是按顺序弄,换句话说就是暴力?
我从第一个数字开始,answer[0][0]先设置为1,我就记录当前数组的横纵坐标x,y,然后走下去就OK了
具体思路是这样的,首先我的x,y 都等于0,对于每个位置来说,有4个状态,向右、向下、向左、向上
我从0,0出发,一开始必然向右走,直到走到3,然后转换当前的状态,转为向下走
所以我们只需要注意到怎样转移行走的状态就行了
很明显,到3的时候,我们再往右走就会越界,所以我们要把状态转为向下走
还有一种情况就是,遇到了已走过的点,也要转移状态
我的详细解法就如下:
首先用一个boolean类型的check数组,记录是否走完整个n*n矩阵,走过的点标记为true,循环停止条件就是把整个矩阵走完
然后用4个状态来控制当前点下一步的行进方向,当下一步越界或者去到了已走过的点,就把当前状态转移,进行下一次循环
状态转移顺序就按照右-下-左-上-右..这样循环就好
代码如下:
class Solution {
public int[][] generateMatrix(int n) {
int answer[][] = new int[n][n];
boolean check[][] = new boolean[n][n];
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++)
check[i][j] = false;
}
check[0][0] = true;
answer[0][0] = 1;
int state = 1;
int x = 0;
int y = 0;
int counter = 2;
while(if_full(check,n) == false){
int temp_x = x;
int temp_y = y;
switch(state)
{
case 1:
y++;
//如果下一步越界或者是到达已走过的点,就停在当前位置,并转到下一个状态,即下一次的移动方向
if(y >= n || check[x][y] == true){
y--;
state = 2;
}
break;
case 2:
x++;
if(x >= n || check[x][y] == true){
x--;
state = 3;
}
break;
case 3:
y--;
if(y < 0 || check[x][y] == true){
y++;
state = 4;
}
break;
case 4:
x--;
if(x < 0 || check[x][y] == true){
x++;
state = 1;
}
break;
}
//如果位置没变化,说明转移了状态,也就是没进行移动,直接进行下一次循环
if(x == temp_x && y == temp_y)
continue;
//位置发生变化,那就把当前位置标记为true,也就是已走到了,同时给answer赋值
else{
check[x][y] = true;
answer[x][y] = counter;
counter++;
}
}
return answer;
}
public boolean if_full(boolean check[][],int n){
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
if(check[i][j] == false)
return false;
}
}
return true;
}
}