题目传送门:
L54.螺旋矩阵
L59.螺旋矩阵II
先贴代码, 这些代码都能顺利通过
//L54.螺旋矩阵
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<Integer>();
int len = matrix[0].length;
int tall = matrix.length;
int d = 1;
int x = 0, y = 0;
int totalNum = len*tall;
int num = 0;
boolean[][] isVisited = new boolean[tall][len];
while(true){
if(isVisited[x][y] == false){
isVisited[x][y] = true;
res.add(matrix[x][y]);
++num;
}
if(d == 1 && y+1<len && isVisited[x][y+1] == false){
++y;
}else{
d = 2;
}
if(d == 2 && x+1<tall && isVisited[x+1][y] == false){
++x;
}else{
d = 3;
}
if(d == 3 && y-1>=0 && isVisited[x][y-1] == false){
--y;
}else{
d = 4;
}
if(d == 4 && x-1>=0 && isVisited[x-1][y] == false){
--x;
}else{
d = 1;
}
if(num == totalNum){
break;
}
}
return res;
}
}
//L59.螺旋矩阵II
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
boolean[][] isVisited = new boolean[n][n];
int num = 0;
int totalNum = n * n;
int d = 1;
int x = 0, y = 0;
while(num<totalNum){
if(isVisited[x][y] == false){
res[x][y] = num+1;
isVisited[x][y] = true;
++num;
}
if(d == 1 && y+1 < n && isVisited[x][y+1] == false){
++y;
}else{
d = 2;
}
if(d == 2 && x+1 < n && isVisited[x+1][y] == false){
++x;
}else{
d = 3;
}
if(d == 3 && y-1 >= 0 && isVisited[x][y-1] == false){
--y;
}else{
d = 4;
}
if(d == 4 && x-1 >= 0 && isVisited[x-1][y] == false){
--x;
}else{
d = 1;
}
}
return res;
}
}
当时写的题解:
- 两道题共同的特点都是要控制好方向的转变时机, 由于都是从
[0,0]
位置开始顺时针前进, 不如就在程序开始处就建立变量x
和y
指向起点, 将该位置处的数据处理完后再寻找条件对x
和y
进行判断, 然后重复处理指向新位置的x
和y
判断x和y更新的条件总共有三个:
1.当前位置的下一个位置是否已经被访问过
2.当前的方向是什么方向, 如果需要变更方向, 新的方向是什么
3.x和y是否越界, 超出了二维矩阵的范围
- 对于1, 解决的方法是定义一个与所需遍历矩阵大小相同的
boolean
类型的数组isVisied
, 初始全部是false
, 每当一个元素被访问过后就会变成true
- 对于2, 解决的方法是定义一个变量
d
,d = 1
时代表向右走(d
初始化为1
),d = 2
时代表向下走,d = 3
时代表向左走,d = 4
时代表向上走, 在判断x
和y
该如何更新时, 如果不满足以上三个条件, 就要按顺时针方向换一个方向重新判断, 比如1完了是2,2完了是3… - 对于3, 只需要注意
x
和y
在加1减1时不要越界即可
其实这个代码是不合理的, 只是能碰巧正确通过罢了
当d
等于一个数后会继续进行判断, 之后的三个if碰巧都进入了else
当中, 最终d
又等于回了原来的数, 原来的想法是四个if
只要有一个if
判断了其余的if
就自动跳过了, 但是事实上并没有跳过, 只是巧合让d
的值更新多次后又回到了原来的值, 这个方法在做L885.螺旋矩阵 III时就不能用了
总结
- 有时候编程还是有一点想当然了, 自己想怎么样就怎么样, 其实每一条语句都有严格的执行逻辑, 有时候自己想的并不能准确的落实在代码上, 光说不练假把式, 练固然重要, 但是走都走不明白就先别想着跑
- 点开之前自己做的题目, 如果再做一遍的话还是有很多都没有思路, 有相当一部分的题都是之前看完题解懂了, 之后又忘记了
- 刷题在精而不在多, 最近应该把做过题都再做做, 会一种解法了还要再会另一种解法, 争取只要是做过的题就一定会