更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~
T:
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
例如,如果输入如下矩阵:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
则依次打印出数字
1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
constraints:
时间限制:1秒空间限制:32768K
顺时针循环,大圈小圈的,都需要经过四条路径:
- 从左到右 ⟶ \longrightarrow ⟶;
- 从上到下 ↓ \downarrow ↓;
- 从右到左 ⟵ \longleftarrow ⟵;
- 从下到上 ↑ \uparrow ↑;
既然知道了以上的四步,那就是本体的核心思想了,还一个要注意的就是:对于正在遍历的每一个节点来说,其后继节点,一定会从以上4步中的某一步中得来,即:
如果还有节点没有访问到,那么该节点之后,至少可以走以上四步当中的一步,否则的话,那就说明该二维数组已经都遍历完了。
code:
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> dataList = new ArrayList<Integer>();
// 初始化一个专门用于标记的数组
int [][] tempMatrix = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
tempMatrix[i][j] = 1;
}
}
int i = 0;
int j = 0;
// 外层的大循环,每一次循环,就是顺时针的一圈(前提是当前数据还没有被扫描过)
while (true) {
boolean flag = false; // 在一个大循环中,四个方向是不是还有地方可以走
//向右
while (j < matrix[0].length && tempMatrix[i][j] == 1) {
tempMatrix[i][j] = 0;
dataList.add(matrix[i][j]);
flag = true;
j ++;
}
j -= 1; // 已经过了头,要回退一个单位,下同
i ++; // 已经走过的路,已经做了标记,这地方要继续往下走一步,下同
// 向下
while (i < matrix.length && tempMatrix[i][j] == 1) {
tempMatrix[i][j]= 0;
dataList.add(matrix[i][j]);
flag = true;
i ++;
}
i -= 1;
j --;
// 向左
while (j > -1 && tempMatrix[i][j] == 1) {
tempMatrix[i][j] = 0;
dataList.add(matrix[i][j]);
flag = true;
j --;
}
j += 1;
i--;
// 向上
while (i > -1 && tempMatrix[i][j] == 1) {
tempMatrix[i][j] = 0;
dataList.add(matrix[i][j]);
flag = true;
i --;
}
i += 1;
j ++;
if (!flag) { // 当四处都没地方可走时,表示整个都已经遍历了一遍,就退出外部的while循环
break;
}
}
return dataList;
}
更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~