输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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]);
}
}
}
}
/*解题思路:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况*/ class Solution { public: vector<int> printMatrix(vector<vector<int> > matrix) { vector<int>res; res.clear(); int row=matrix.size();//行数 int collor=matrix[0].size();//列数 //计算打印的圈数 int circle=((row<collor?row:collor)-1)/2+1;//圈数 for(int i=0;i<circle;i++){ //从左向右打印 for(int j=i;j<collor-i;j++) res.push_back(matrix[i][j]); //从上往下的每一列数据 for(int k=i+1;k<row-i;k++) res.push_back(matrix[k][collor-1-i]); //判断是否会重复打印(从右向左的每行数据) for(int m=collor-i-2;(m>=i)&&(row-i-1!=i);m--) res.push_back(matrix[row-i-1][m]); //判断是否会重复打印(从下往上的每一列数据) for(int n=row-i-2;(n>i)&&(collor-i-1!=i);n--) res.push_back(matrix[n][i]);} return res; } };