面20
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
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.
思路:
顺时针打印,读取的顺序是有规律的,即往右,往下,往左,往上。因此可以写一个循环。并且声明一个list变量,往list中按顺序存放数据,当list中变量数量等于数组大小时,跳出while循环。
一开始写的程序报错:
报错:
测试用例:
[[1]]
对应输出应该为:
[1]
你的输出为:
java.lang.ArrayIndexOutOfBoundsException: 1
public static ArrayList<Integer> printMatrix(int [][] matrix) {
if(matrix==null)
return null;
int m = matrix.length;
int n = matrix[0].length;
if(m==0||n==0)
return null;
int[][] flag = new int[m][n];
int num = m*n;
ArrayList<Integer> list = new ArrayList();
while(list.size()!=num){
int i = 0;
int j = 0; // 这个位置也有问题,每次while循环会重新置0
for(;j<n;j++){
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
} // 这里一开始跳出循环是因为j越界
for(;i<m;i++){
if(flag[i][j]!=1){ // 不加处理,继续用越界的j,就出现指针越界错误
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
for(;j>=0;j--){
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
for(;i>=0;i--){
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
}
return list;
}
AC代码:
public static ArrayList<Integer> printMatrix(int [][] matrix) {
if(matrix==null)
return null;
int m = matrix.length;
int n = matrix[0].length;
if(m==0||n==0)
return null;
int[][] flag = new int[m][n];
int num = m*n;
ArrayList<Integer> list = new ArrayList();
int i = 0;
int j = 0;
list.add(matrix[0][0]);
flag[0][0] = 1; //为了构成之后能够循环的逻辑,把第一个元素放在了循环体外
while(list.size()!=num){
for(++j;j<n;j++){ //直接++j
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
--j; // 因为跳出前面for循环有两种情况,一种是越界,一种是遇到了已经被访问过的元素,所以,都需要将j减1
for(++i;i<m;i++){
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
--i;
for(--j;j>=0;j--){
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
++j;
for(--i;i>=0;i--){
if(flag[i][j]!=1){
list.add(matrix[i][j]);
flag[i][j] = 1;
}
else
break;
}
++i;
}
return list;
}
不需要boolean数组也可以,因为按照规律来就能正确遍历
public class Printer {
public int[] clockwisePrint(int[][] mat, int n, int m) {
// write code here
int startX = 0;
int endX = m - 1;
int startY = 0;
int endY = n - 1;
int index = 0;
int[] result = new int[n * m];
while (startX <= endX && startY <= endY) {
// 从左到右打印
if(startX <= endX){
for (int i = startX; i <= endX; i++) {
result[index++] = mat[startY][i];
}
}
// 从上往下打印
if (startY < endY) {
for (int i = startY + 1; i <= endY; i++) {
result[index++] = mat[i][endX];
}
}
// 从右往左打印
if (startX < endX && endY > startY) {
for (int i = endX - 1; i >= startX; i--) {
result[index++] = mat[endY][i];
}
}
// 从下往上打印
if (startY < endY && endX > startX) {
for (int i = endY - 1; i >= startY + 1; i--) {
result[index++] = mat[i][startX];
}
}
startX++;
endX--;
startY++;
endY--;
}
return result;
}
}
or
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
int flag = Integer.MAX_VALUE;
ArrayList<Integer> list = new ArrayList<>();
int startLine = 0;
int startRow = -1;
while(list.size()!=n*m){
for(int j = startRow+1; j<m; j++){
if(matrix[startLine][j]!=flag){
list.add(matrix[startLine][j]);
matrix[startLine][j] = flag;
if(j==m-1) startRow = j;
}
else{
startRow = j-1;
break;
}
}
for(int i = startLine+1; i<n; i++){
if(matrix[i][startRow]!=flag){
list.add(matrix[i][startRow]);
matrix[i][startRow] = flag;
if(i==n-1) startLine = i;
}
else{
startLine = i-1;
break;
}
}
for(int j = startRow-1; j>=0 ; j--){
if(matrix[startLine][j]!=flag){
list.add(matrix[startLine][j]);
matrix[startLine][j] = flag;
if(j==0) startRow = j;
}
else{
startRow = j+1;
break;
}
}
for(int i = startLine-1; i>=0; i--){
if(matrix[i][startRow]!=flag){
list.add(matrix[i][startRow]);
matrix[i][startRow] = flag;
if(i==0) startLine = i;
}
else{
startLine = i+1;
break;
}
}
}
return list;
}
}