输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵:
[[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]数据范围:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
[[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]数据范围:
[[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]
[[1,2,3,1],[4,5,6,1],[4,5,6,1]]
[1,2,3,1,1,1,6,5,4,4,5,6]
public class Solution { ArrayList<Integer> arr = new ArrayList<Integer>(); public ArrayList<Integer> printMatrix(int [][] matrix) { if (matrix.length == 0) { return arr; } deal(matrix, 0, 0, matrix.length - 1, matrix[0].length - 1); return arr; } /** * deal函数只处理一圈数据 * beginX 当前圈x轴的起始下标 * beginY 当前圈y轴的起始下标 * maxX 当前圈x轴的最大下标 * maxY 当前圈y轴的最大下标 */ public void deal(int [][] matrix, int beginX, int beginY, int maxX, int maxY) { if (beginX == maxX && beginY == maxY) { arr.add(matrix[beginX][beginY]); return; } if (beginX + 1 > maxX && beginY + 1 > maxY || maxX < 0 || maxY < 0) { return; } for (int y = beginY; y <= maxY; y++) { arr.add(matrix[beginX][y]); } for (int x = beginX + 1; x <= maxX; x++) { arr.add(matrix[x][maxY]); } for (int y = maxY - 1; y >=beginY && beginX!=maxX; y--) { arr.add(matrix[maxX][y]); } for (int x = maxX - 1; x >beginX&& beginY!=maxY; x--) { arr.add(matrix[x][beginY]); } if(beginX + 1 != maxX && beginY + 1 != maxY){ deal(matrix, beginX + 1, beginY + 1, maxX - 1, maxY - 1); } } }
int[][] dis = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int m = matrix.length; int n = matrix[0].length; // 访问标记数组 int[][] vis = new int[m][n];代码如下:
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { int[][] dis = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int dx = 0; int m = matrix.length; if (m == 0) return new ArrayList<Integer>(); int n = matrix[0].length; if (n == 0) return new ArrayList<Integer>(); int sx = 0, sy = 0, ex = m - 1, ey = n - 1, x = 0, y = 0; // 访问标记数组 int[][] vis = new int[m][n]; ArrayList<Integer> res = new ArrayList<>(); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) vis[i][j] = 0; int num = 0; while (sx <= x && x <= ex && sy <= y && y <= ey) { if (vis[x][y] == 0) { res.add(matrix[x][y]); vis[x][y] = 1; } // 若某个数字四周都是矩阵之外或者已经被访问过,则退出循环 if ((x + 1 > ex || vis[x + 1][y] == 1) && (x - 1 < sx || vis[x - 1][y] == 1) && (y + 1 > ey || vis[x][y + 1] == 1) && (y - 1 < sy || vis[x][y - 1] == 1)) break; x += dis[dx][0]; y += dis[dx][1]; // 若到边界或者下一个已经访问过,则更改方向 if (x < sx || x > ex || y < sy || y > ey || vis[x][y] == 1) { x -= dis[dx][0]; y -= dis[dx][1]; dx = (dx + 1) % 4; x += dis[dx][0]; y += dis[dx][1]; } } return res; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { ArrayList<Integer> res = new ArrayList<>(); int m = matrix.length; int n = matrix[0].length; int length = m * n; int i = 0, j = 0; int rowTop = 0; int rowBottom = m - 1; int colLeft = 0; int colRight = n - 1; while (length > 0) { while (j <= colRight && length > 0) { res.add(matrix[i][j++]); length--; } j--; i++; rowTop = rowTop + 1; while (i <= rowBottom && length > 0) { res.add(matrix[i++][j]); length--; } i--; j--; colRight = colRight - 1; while (j >= colLeft && length > 0) { res.add(matrix[i][j--]); length--; } j++; i--; rowBottom = rowBottom - 1; while (i >= rowTop && length > 0) { res.add(matrix[i--][j]); length--; } i++; j++; colLeft = colLeft + 1; } return res; } }
import java.util.*; import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { int row=matrix.length,col=matrix[0].length; int a=0; int size=row*col; ArrayList<Integer> list=new ArrayList<>(); while(size!=0){ for(int i=a;i<col;i++,size--){ list.add(matrix[a][i]); } if(size==0)break; for(int j=a+1;j<row;j++,size--){ list.add(matrix[j][col-1]); } if(size==0)break; for(int k=col-2;k>=a;k--,size--){ list.add(matrix[row-1][k]); } for(int r=row-2;r>=a+1;r--,size--){ list.add(matrix[r][a]); } a++;row--;col--; } return list; } }
import java.util.ArrayList; public class Solution { ArrayList<Integer> res = new ArrayList<>(); public ArrayList<Integer> printMatrix(int [][] matrix) { if(matrix == null || matrix.length == 0) return res ; int x = 0; int y = 0; //起始点 String flag = "right"; //移动的标志位 int row = matrix.length ; int col = matrix[0].length ; boolean[][] isVisited = new boolean[row][col]; while(res.size() < row * col) { //没遍历完就继续遍历 //满足这些条件表示需要变更移动方向 if(x < 0 || x >= row || y < 0 || y >= col || isVisited[x][y]){ if(flag.equals("right")) { //如果此时标志位是right 则需要向下移动 x ++; y --; //此时y已经越界了 所以需要--挪回来 flag = "down"; }else if (flag.equals("down")) { x --; //此时x已经越界了 需要--挪回来 y --; flag = "left"; }else if(flag.equals("left")) { x -- ; y ++; flag = "up"; }else if (flag.equals("up")) { x ++; y ++; flag = "right"; } } else { res.add(matrix[x][y]); isVisited[x][y] = true; if(flag.equals("right")) { y ++; }else if(flag.equals("down")) { x ++; }else if(flag.equals("left")) { y --; }else if(flag.equals("up")) { x --; } } } return res; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int[][] matrix) { ArrayList<Integer> ans = new ArrayList<>(); boolean[][] flag = new boolean[matrix.length][matrix[0].length]; int size = matrix.length * matrix[0].length; int dir = 0; int x = 0; int y = 0; for (int i = 0; i < size; i++) { ans.add(matrix[x][y]); flag[x][y] = true; if (dir == 0) { if (y + 1 == matrix[0].length || flag[x][y + 1]) { dir++; x++; continue; } y++; } else if (dir == 1) { if (x + 1 == matrix.length || flag[x + 1][y]) { dir++; y--; continue; } x++; } else if (dir == 2) { if (y == 0 || flag[x][y - 1]) { dir++; x--; continue; } y--; } else if (dir == 3) { if (x == 0 || flag[x - 1][y]) { dir = 0; y++; continue; } x--; } } return ans; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { ArrayList<Integer> ret = new ArrayList<Integer>(); // 边界判空 if(matrix.length==0 || matrix[0].length==0){ return ret; } // 定义4个边界 int up=0; int down=matrix.length-1; int left=0; int right=matrix[0].length-1; // 每遍历一行,向内挤压一行(对应边界+1或-1),遵循顺时针顺序(up-right-down-left) while(true){ // 从left到right遍历 for(int i=left;i<=right;i++){ ret.add(matrix[up][i]); } // 上边界下移1 up++; // 边界溢出则返回 if(up>down) break; // 从up到down遍历 for(int i=up;i<=down;i++){ ret.add(matrix[i][right]); } // 右边界左移1 right--; // 边界溢出则返回 if(left>right) break; // 从right到left遍历 for(int i=right;i>=left;i--){ ret.add(matrix[down][i]); } // 下边界上移1 down--; // 边界溢出则返回 if(up>down) break; // 从down到up遍历 for(int i=down;i>=up;i--){ ret.add(matrix[i][left]); } // 左边界右移1 left++; // 边界溢出则返回 if(left>right) break; } return ret; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { int up = 0, down = matrix.length - 1; int left = 0, right = matrix[0].length - 1; ArrayList<Integer> list = new ArrayList<>(); while (up <= down && left <= right) { for (int i = left; i <= right; i ++) { list.add(matrix[up][i]); } up ++; for (int i = up; i <= down; i ++) { list.add(matrix[i][right]); } right --; if (down >= up) { for (int i = right; i >= left; i --) { list.add(matrix[down][i]); } down --; } if (left <= right) { for (int i = down; i >= up; i --) { list.add(matrix[i][left]); } left ++; } } return list; } }
import java.util.ArrayList; public class Solution { ArrayList<Integer> res = new ArrayList<>(); public ArrayList<Integer> printMatrix(int [][] matrix) { int height = matrix.length; int length = matrix[0].length; int times = (Math.min(height,length)+1)/2; int start = 0; while(times>0){ rotate(start,matrix); start++; times--; } return res; } public void rotate(int start, int [][] matrix){ int left_height = matrix.length-start*2; int left_length = matrix[0].length-start*2; for(int i = start; i<start+left_length; i++){ res.add(matrix[start][i]); } if(left_height > 1){ for(int i = start+1; i<start+left_height; i++){ res.add(matrix[i][start+left_length-1]); } } if(left_height > 1){ for(int i = start+left_length-2;i>=start;i--){ res.add(matrix[start+left_height-1][i]); } } if(left_length >= 2){ for(int i = start+left_height-2; i>start; i--){ res.add(matrix[i][start]); } } } }
import java.util.ArrayList; public class Solution { static ArrayList<Integer> res = new ArrayList<>(); public static ArrayList<Integer> printMatrix(int[][] matrix) { int s = matrix.length * matrix[0].length; if (s==0)return res; return printMatrix(matrix, 0, 0, s, 0, res); } public static ArrayList printMatrix(int[][] ints, int p, int q, int s, int cnt, ArrayList res) { int R = ints.length; int C = ints[0].length; int i = p; int j = q; int count = 0; int c = C - q; int r = R - p; int sum; if (C - 2 * q == 1 || R - 2 * p == 1) sum = (C - 2 * q )*(R - 2 * p); else { sum = (C - 2 * q) * 2 + ((R - 2 * p) - 2) * 2; } out: while (true) { while (j < c) { //System.out.print(ints[i][j] + " "); res.add(ints[i][j]); count++; if (count >= sum) break out; j++; } j--; i++; while (i < r) { // System.out.print(ints[i][j] + " "); res.add(ints[i][j]); count++; if (count >= sum) break out; i++; } i--; j--; while (j >= q) { // System.out.print(ints[i][j] + " "); res.add(ints[i][j]); count++; if (count >= sum) break out; j--; } j++; i--; while (i >= p ) { // System.out.print(ints[i][j] + " "); res.add(ints[i][j]); count++; if (count >= sum) break out; i--; } } if (s == cnt + count) { return res; } else { return printMatrix(ints, p + 1, q + 1, s, cnt + count, res); } } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { int n=matrix.length; int m=matrix[0].length; ArrayList<Integer> list=new ArrayList<>(); if(n==0&&m==0) return list; int up=0; int l=0; while(true){ for(int i=l;i<m;i++){ list.add(matrix[up][i]); } up++; if(n-1<up) break; for(int i=up;i<n;i++){ list.add(matrix[i][m-1]); } m--; if(m-1<l) break; for(int i=m-1;i>=l;i--){ list.add(matrix[n-1][i]); } n--; if(n-1<up) break; for(int i=n-1;i>=up;i--){ list.add(matrix[i][l]); } l++; if(m-1<l) break; } return list; } }
public ArrayList<Integer> printMatrix(int [][] matrix) { if(matrix.length==0) return null; ArrayList<Integer> list = new ArrayList<>(); int minx = 0,miny = 0,maxx = matrix[0].length,maxy = matrix.length,i,j; int sum = maxx*maxy; maxx--; maxy--; while(sum!=0){ for(i = minx;i<=maxx&&sum!=0;i++){ list.add(matrix[miny][i]); sum--; } miny++; for(j = miny;j<=maxy&&sum!=0;j++){ list.add(matrix[j][maxx]); sum--; } maxx--; for(i = maxx;i>=minx&&sum!=0;i--){ list.add(matrix[maxy][i]); sum--; } maxy--; for(j = maxy;j>=miny&&sum!=0;j--){ list.add(matrix[j][minx]); sum--; } minx++; } return list; }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int [][] matrix) { int row = matrix.length; int column = matrix[0].length; ArrayList<Integer> resList = new ArrayList<>(); int rowBottom = 0,rowTop = row-1,columnBottom = 0,columnTop = column-1; //用边界变量来作为循环结束条件 while((rowBottom <= rowTop) && (columnBottom <= columnTop)){ //选择第一行整行访问 for(int j = columnBottom;j <= columnTop;j++) resList.add(matrix[rowBottom][j]); for(int i = rowBottom+1;i <= rowTop;i++) resList.add(matrix[i][columnTop]); //加上if来解决单行单列重复添加的问题 if(rowBottom != rowTop) for(int j = columnTop-1;j >= columnBottom;j--) resList.add(matrix[rowTop][j]); if(columnBottom != columnTop) for(int i = rowTop-1;i > rowBottom;i--) resList.add(matrix[i][columnBottom]); rowBottom++; rowTop--; columnBottom++; columnTop--; } return resList; } }
我们注意到,左上角的坐标中行号和列号总是相同的,于是可以在矩阵中选取左上角为 (start, start) 的一圈作为我们分析的目标。经过分析,不论是5*5还是6*6的矩阵,左上角的坐标都符合start * 2 < matrix.length && start * 2 < matrix[start].length,所以可以以此为循环条件按圈打印矩阵。
接下来考虑如何打印一圈的数字。我们可以把打印一圈分为四步:第一步,从左到右打印一行;第二步,从上到下打印一列;第三步,从右到左打印一行;第四步,从下到上打印一列。需要注意的是,最后一圈有可能退化成只有一行、只有一列,甚至只有一个数字,因此打印这样的一圈就不需要四步了。
import java.util.ArrayList; public class Solution { public ArrayList<Integer> printMatrix(int[][] matrix) { if (matrix == null || matrix.length == 0) { return new ArrayList<>(0); } int start = 0; ArrayList<Integer> list = new ArrayList<>(matrix.length * matrix[0].length); // 使用乘2而不是除2, 可以避免奇偶数的差异 while (start * 2 < matrix.length && start * 2 < matrix[start].length) { printMatrix(matrix, start, matrix.length - 2 * start, matrix[start].length - 2 * start, list); start++; } return list; } // 一圈的范围是[start, start] ~ [start+rows-1, start+cols-1] public void printMatrix(int[][] matrix, int start, int rows, int cols, ArrayList<Integer> list) { // 第一步, 肯定要执行 for (int i = start, j = start; j < start + cols; j++) { list.add(matrix[i][j]); } // 第二步, 前提条件是圈内至少有两行 if (rows >= 2) { for (int i = start + 1, j = start + cols - 1; i < start + rows; i++) { list.add(matrix[i][j]); } } // 第三步, 前提条件是圈内至少有两行两列 if (rows >= 2 && cols >= 2) { for (int i = start + rows - 1, j = start + cols - 2; j >= start; j--) { list.add(matrix[i][j]); } } // 第四步, 前提条件是圈内至少有三行两列 if (rows >= 3 && cols >= 2) { for (int i = start + rows - 2, j = start; i > start; i--) { list.add(matrix[i][j]); } } } }