首页 > 试题广场 > 顺时针打印矩阵
[编程题]顺时针打印矩阵
  • 热度指数:784756 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
推荐
/*解题思路:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况*/
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;
    }
};


编辑于 2015-09-07 13:31:21 回复(52)
四个方向遍历,其实每次选择的只有两个方向,若不是沿原来的方向行进,就按照{右下左上}选择下一个方向行进,通过两个条件判断选择哪个方向:1)行列值是否在范围内;2)下一个元素是否已经被遍历。判断好方向后,按照所选择的方向改变下标值。
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       ArrayList<Integer> array=new ArrayList<Integer>();
            if (matrix==null)return null;
            
            int row=matrix.length;
            int col=matrix[0].length;

            int i=0,j=0;//行和列
            int k=0;//k=0-向右;k=1-向下;k=2-向左;k=3-向上
            //第一步:确定向哪个方向遍历
            while(array.size()<row*col) {
                array.add(matrix[i][j]);
                if(k==0) {
                    //判断右边是否已经遍历
                    if(j<col-1&&!array.contains(matrix[i][j+1])) k=0;
                    else k=1;
                }
                else if(k==1) {
                    //判断下边是否遍历
                    if(i<row-1&&!array.contains(matrix[i+1][j])) k=1;
                    else k=2;
                }
                else if(k==2) {
                    //判断左边是否遍历
                    if(j>0&&!array.contains(matrix[i][j-1])) k=2;
                    else k=3;
                }
                else if(k==3) {
                    if(i>0&&!array.contains(matrix[i-1][j])) k=3;
                    else k=0;
                }
                
                switch(k) {
                case 0:j++;break;
                case 1:i++;break;
                case 2:j--;break;
                case 3:i--;break;
                }
            }
            
            return array;
    }
}

发表于 2020-05-25 09:58:32 回复(0)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
            int i=0;
            int j=0;
            int count =0;
            int g =0;
            int maxcol = matrix[0].length-1;
            int mincol = 0;
            int maxrow = matrix.length-1;
            int minrow = 0;
            ArrayList<Integer> list = new ArrayList<Integer>();
            while(count<(matrix.length)*(matrix[0].length)){
                count++;
                list.add(matrix[i][j]);
               // System.out.println(matrix[i][j]);
                if(g%4==0){
                    if(j<maxcol) j++;
                    else if(j==maxcol) {g++;minrow++;}
                }
                if(g%4==1){
                    if(i<maxrow) i++;
                    else if(i==maxrow) {g++;maxcol--;}
                }
                if(g%4==2){
                    if(j>mincol) j--;
                    else if(j==mincol) {g++;maxrow--;}
                }
                if(g%4==3){
                    if(i>minrow) i--;
                    else if(i==minrow) {j++;g++;mincol++;}//注意这里j++,因为每次一圈如果不j++,当走到左上角时,它在这里无操作,然后会重复输出一次,所以需要主动挪一下
                }
            }
        return list;
        
    }
}
发表于 2020-05-18 11:55:53 回复(0)
数组每次add矩阵的一行元素,每次循环add一行之后,逆时针旋转数组
import java.util.*;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        if ((matrix == null || matrix[0]==null||matrix[0].length==0)){
            return null;
        }

        ArrayList<Integer> list = new ArrayList<>();

        while (matrix!=null){
            for (int i=0; i<matrix[0].length; i++){
                list.add(matrix[0][i]);
            }
            matrix = turnMatrix(matrix);
        }
        return list;
    }

    /**
    *旋转数组
    */
    public int[][] turnMatrix(int [][] matrix){
        if(matrix.length == 1){
            return null;
        }
        int[][] newMatrix = new int[matrix[0].length][matrix.length-1];
        for (int i=1; i<matrix.length; i++){
            for (int j=0; j<matrix[0].length; j++){
                newMatrix[j][i-1] = matrix[i][matrix[0].length-1-j];
            }
        }
        return newMatrix;
    }
}


发表于 2020-05-09 11:44:59 回复(0)
/*
考虑4*4的一种情况:
用 lie=i,hang=j 进行遍历
首先从最外层开始计数,当lie到最大值时,开始转向下;
然后当i=j时,像左i开始减小;当i等于0时,向上转向,j开始增加。当j-i的值等于1时,如果直接等于1则break 结束遍历。如果j-i是逐步减少到=1的,说明还可以继续遍历,再次遍历的时候行、列的边界值要加+1;


*/


import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        
        
        int lie_max = matrix[0].length-1;
        int hang_max = matrix.length-1;
        int lie=0;
        int hang=0;
        ArrayList<Integer> printMatrix = new ArrayList<>();
        
            if(matrix == null || lie_max == 0 )
            {
                for(int i=0;i<=hang_max;i++)
                    printMatrix.add(matrix[i][lie_max]);
                return printMatrix;
            }else if(matrix == null || hang_max == 0 )
            {
                for(int i=0;i<=lie_max;i++)
                    printMatrix.add(matrix[hang_max][i]);
                return printMatrix;
            }
        
            else{
           
            for(int i=lie;i<=lie_max;i++)
            {
                int m=i;
                printMatrix.add(matrix[hang][m]);
               
                  if(m==lie_max)
                  {
                      for(int j=hang+1;j<=hang_max;j++)
                      {
                          printMatrix.add(matrix[j][m]);
                          if(j==hang_max)
                          {
                              int x=j;
                             while(m>=lie)
                             {
                                 --m;
                                 printMatrix.add(matrix[x][m]);
                                 if(m==lie)
                                 { 
                                     if((x-m)==1)
                                     {
                                         break;
                                      }   
                                     while((x-m)>=1)
                                     {
                                         if((x-m)==1)
                                         {
                                            
                                            lie++;
                                            hang++;
                                            lie_max--;
                                            hang_max--;
                                            i=lie-1;
                                            break;
                                         }else{

                                         --x;
                                         printMatrix.add(matrix[x][m]);
                                         }

                                     
                                     }

                                  }      
                                         
                             }
                              
                          }
                      }
                  }
            }
            
            

            }

    return printMatrix;
        
    }
}
发表于 2020-04-29 18:02:05 回复(0)
import java.util.ArrayList;
public class Solution {
    
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        
       ArrayList<Integer> list =  new ArrayList<>();
       printMatrixClockWisely(matrix,0,list);
       return list;
    }
    
   
    public static ArrayList<Integer> printMatrixClockWisely(int[][] arr, int start, ArrayList<Integer> list) {

        //鲁棒性
        if (arr == null || arr.length == 0 || list == null) {
            return list;
        } else if (start * 2 >= arr.length || start * 2 >= arr[0].length) { //递归的临界条件
            return list;
        } else {
            int rows = arr.length;
            int cols = arr[0].length;

            //从左向右打印
            for (int j = start; j <= cols - 1 - start; j++) {
                list.add(arr[start][j]);
            }

            //从上向下打印
            for (int i = start + 1; i <= rows - 1 - start; i++) {
                list.add(arr[i][cols - 1 - start]);
            }

            //从右向左打印
            if (start != rows - 1 - start) { //防止最后一行就是第一行
                for (int j = cols - 1 - start - 1; j >= start; j--) {
                    list.add(arr[rows - 1 - start][j]);
                }

            }

            //从上向下打印 
            if (start != cols - 1 - start) { //防止最后一列就是第一列
                for (int i = rows - 1 - start - 1; i >= start + 1; i--) {
                    list.add(arr[i][start]);
                }
            }

            return printMatrixClockWisely(arr, start + 1, list);

        }
    }

}

发表于 2020-04-27 17:25:21 回复(0)
模拟走的路,顺时针走。代码类似深度优先遍历,但是由于只需要存储一个点,而且不需要遍历四个方向,只用遍历当前直线方向,因此不用栈或者队列。当超出数组范围或者已经访问过。就就改变方向。
退出循环条件是,当前无法走到下一个点的时候跳转,即碰壁4次(其实两次就可以推出了)
public static ArrayList<Integer> printMatrix(int [][] matrix) {
        int[] move_i = {0,1,0,-1}; // 右下左上 顺序走(顺时针)
        int[] move_j = {1,0,-1,0};
        ArrayList<Integer> ans = new ArrayList<>();
        int m = matrix.length;
        int n = matrix[0].length;
        boolean[][] visited = new boolean[m][n];
        ans.add(matrix[0][0]);
        visited[0][0] = true;
        int count=0;
        int i=0,j=0,k=0;
        while (count<4){
            int newI = i + move_i[k];
            int newJ = j + move_j[k];
            if (newI<0||newI>=m||newJ<0||newJ>=n||visited[newI][newJ]){
                k++; // 碰壁了
                count++; // 碰四次就推出
                if (k==4) k=0;
                continue;
            }
            count = 0;
            ans.add(matrix[newI][newJ]);
            visited[newI][newJ] = true;
            i = newI;
            j = newJ;
        }
        return ans;
    }


发表于 2020-04-24 21:12:56 回复(0)
    public static ArrayList<Integer> printMatrix(int [][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        ArrayList<Integer> arrayList = new ArrayList<>();


        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return arrayList;
        }

        int cur_index_row_start = 0;
        int cur_index_row_end = 1;
        int cur_index_col_start = 0;
        int cur_index_col_end = 1;

//        for (int i = cur_index_row_start; i <= rows - cur_index_row_end; i++) {
        while(true) {
            //上方行按列依次增加
            for (int j = cur_index_col_start; j <= cols - cur_index_col_end; j++) {
                arrayList.add(matrix[cur_index_row_start][j]);
            }
            cur_index_row_start += 1;
            // 判断是否越界
            if(cur_index_row_start > rows - cur_index_row_end){
                break;
            }
            //右方列按行依次添加
            for (int k = cur_index_row_start; k <= rows - cur_index_row_end; k++) {
                arrayList.add(matrix[k][cols - cur_index_col_end]);
            }
            cur_index_col_end += 1;
            // 判断是否越界
            if(cur_index_col_start > rows - cur_index_col_end){
                break;
            }

            //下方行按列依次增加
            for (int b = cols - cur_index_col_end; b >= cur_index_col_start; b--) {
                arrayList.add(matrix[rows - cur_index_row_end][b]);
            }
            cur_index_row_end += 1;
            // 判断是否越界
            if(cur_index_row_start > rows - cur_index_row_end){
                break;
            }
            //左方列按行依次添加
            for (int l = rows - cur_index_row_end; l >= cur_index_row_start; l--) {
                arrayList.add(matrix[l][cur_index_col_start]);
            }
            cur_index_col_start += 1;
            // 判断是否越界
            if(cur_index_col_start > rows - cur_index_col_end){
                break;
            }

        }
        return arrayList;
    }

看起来我和大神的差距变小了,差个判空以及越界的判断。
发表于 2020-04-21 11:05:34 回复(0)
java版魔方旋转
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int[][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        while (matrix.length > 0) {
            for (int i : matrix[0]) {
                list.add(i);
            }
            if (matrix.length ==1){
                return list;
            }
            //构建删除第一行后的数组
            int temp[][] = new int[matrix.length - 1][matrix[0].length];
            for (int i = 1; i < matrix.length; i++) {
                for (int j = 0; j < matrix[i].length; j++) {
                    temp[i - 1][j] = matrix[i][j];
                }
            }
                matrix = arrayRotate(temp);
        }
        return list;
    }
  //数组旋转
    public static int[][] arrayRotate(int[][] matrix) {
        int temp[][] = new int[matrix[0].length][matrix.length];
        for (int i = 0; i < matrix[0].length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                temp[i][j] = matrix[j][matrix[0].length - 1 - i];
            }
        }
        return temp;
    }
}


发表于 2020-04-18 11:23:05 回复(0)
按层数找规律做for循环
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       ArrayList<Integer> res = new ArrayList<>();
        if (matrix.length == 0 || matrix[0].length == 0) return res;
        int m = matrix.length;
        int n = matrix[0].length;
        int lay = (Math.min(m, n) - 1) / 2 + 1;
        for (int i = 0; i < lay; i++) {
            for (int j = i; j < n - i; j++) res.add(matrix[i][j]);
            for (int j = i + 1; j < m - i; j++) res.add(matrix[j][n - i - 1]);
            for (int j = n - i - 2; j >= i && m - i - 1 != i; j--) res.add(matrix[m - i - 1][j]);
            for (int j = m - i - 2; j > i && n - i - 1 != i; j--) res.add(matrix[j][i]);
        }
        return res;
    }
}

发表于 2020-04-17 01:39:05 回复(0)
public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        return printMatrix(matrix, list);
    }
    
    //递归取第一个数组的内容
    public ArrayList<Integer> printMatrix(int [][] matrix, ArrayList<Integer> list) {
        for(int i = 0; i < matrix[0].length; i++){
            list.add(matrix[0][i]);
        }
        if(matrix.length > 1){
            int[][] newMatrix = transMatix(matrix);
            list = printMatrix(newMatrix, list);
        }
        return list;
    }
    
    // 逆时针旋转数组
    public int[][] transMatix(int[][] matrix){
        int x = matrix[0].length - 1;
        int y = matrix.length - 1;
        int[][] newMatrix = new int[x + 1][y];
        int count = 0;
        while(x >= 0){
            // 从上到下,依次把数组的最后一个数作为新数组的记录
            for(int i = 1; i <= y; i ++){
                newMatrix[count][i-1] = matrix[i][x];
            }
            count++;
            x--;
        }
        return newMatrix;
    }

发表于 2020-04-14 08:52:04 回复(0)
package 顺时针打印矩阵;

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
    	ArrayList<Integer> A = new ArrayList<Integer>();
    	int direction = 0;//右0,下1,左2,上3
    	int top = 1;//上界,由于从第一行开始,所以上界初始化1
    	int down = matrix.length-1;
    	int left = 0;
    	int right = matrix[0].length-1;
    	
    	if(matrix.length == 0 && matrix[0].length == 0)
    		return A;
    	
    	int col = 0;
    	int row = 0;
    	
    	int nums  = (down+1) * (right+1);
    	while(nums>0){
    		switch(direction){
	    		case 0:{//→
	    			if(row > right){
	    				//已到达能到达的最右端
	    				direction = 1;//向下
	    				right--;//右端壁垒减1
	    				row--;//自身索引也要减少
	    				col++;//避免重复添加最后一个元素
	    			}else{
	    				A.add(matrix[col][row]);
	    				row++;
	    				direction = 0; //继续向右
	    	    		nums--;
	    			}
	    			break;
	    		}
	    		
	    		case 1:{//↓
	    			if(col > down){
	    				//已到达能到达的最下端
	    				direction = 2;//向左
	    				down--;//下端壁垒加1
	    				col--;//
	    				row--;//避免重复添加最后一个元素
	    			}else{
		    				A.add(matrix[col][row]);
		    				col++;
		    				direction = 1;//继续向下
		    	    		nums--;
	    			}
	    			break;
	    		}
	    		
	    		case 2:{//←
	    			if(row < left){
	    				//已到达能到达的最左端
	    				direction = 3;//向上
	    				left++;//左端壁垒+1
	    				row++;
	    				col--;//避免重复添加最后一个元素
	    			}else{
	    				A.add(matrix[col][row]);
	    				row--;
	    				direction = 2;//继续向左
	    	    		nums--;
	    			}
	    			break;
	    		}
	    		
	    		case 3:{//↑
	    			if(col < top){
	    				//已到达能到达的最上端
	    				direction = 0;//向右
	    				top++;//上端壁垒减1
	    				col++;
	    				row++;//避免重复添加最后一个元素
	    			}else{
	    				A.add(matrix[col][row]);
	    				col--;
	    				direction = 3;//继续向上
	    	    		nums--;
	    			}
	    			break;
	    		}
    		}
    	}
		return A;
       
    }
}


自己琢磨了半天,定义了四个方向,上下左右,以及四个边界值,这应该是最直观的表述,就是在判断转换方向时的边界值时卡了yihuier
发表于 2020-04-13 21:16:52 回复(0)
每次遍历,边界缩小,直至list的个数等于数组
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        int a = matrix.length - 1;
        int b = matrix[0].length - 1;
        int num = (a+1) * (b+1); //二维数组个数
        if (a == 0 && b == 0) {list.add(matrix[0][0]); return list;} //{{1}}
        if (b == 0) { //{{1,2,3}}
            for (int i = 0; i <= a; i++) {
                list.add(matrix[i][0]);
            }
            return list;
        }
        int n1 = 0; //最左
        int n2 = 0; //最上
        int n3 = b; //最右
        int n4 = a; //最下
        while (list.size() != num) {
            for (int i = n1; i <= n3; i++)//从左往右
            {list.add(matrix[n2][i]);}
            n2++; 
            for (int i = n2; i <= n4 && list.size() != num; i++)//从上往下
            {list.add(matrix[i][n3]);}
            n3--;
            for (int i = n3; i >= n1 && list.size() != num; i--)//从右往左
            {list.add(matrix[n4][i]);}
            n4--;
            for (int i = n4; i >= n2 && list.size() != num; i--)//从下往上
            {list.add(matrix[i][n1]);}
            n1++;
        }
        return list;
    }
}

发表于 2020-04-01 13:46:37 回复(0)
按照自己的思路没有做出来;献上大佬的题解,膜拜;
主要是四个特定量的变化和判断,其余都按照正常的遍历;
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return list;
        }
        int up=0,left=0;
        int down=matrix.length-1;
        int right=matrix[0].length-1;
        while(true){
            //最上面一行
            for(int col=left;col<=right;col++){
                list.add(matrix[up][col]);
            }
            //向下逼近
            up++;
            //判断是否越界
            if(up>down) break;
            //最右边一列
            for(int row=up;row<=down;row++){
                list.add(matrix[row][right]);
            }
            //向左逼近
            right--;
            //判断是否越界
            if(left>right) break;
            //最下面一行
            for(int col=right;col>=left;col--){
                list.add(matrix[down][col]);
            }
            //向上逼近
            down--;
            //判断是否越界
            if(up>down) break;
            //最左边一列
            for(int row=down;row>=up;row--){
                list.add(matrix[row][left]);
            }
            //向右逼近
            left++;
            //判断是否越界
            if(left>right) break;
        }
        return list;
    }
}


发表于 2020-03-31 16:19:31 回复(0)

我用的递归

import java.util.ArrayList;
public class Solution {
    ArrayList list=new ArrayList<Integer>();
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       int width=matrix[0].length;
       int high=matrix.length;
       //如果只有一行,直接添加至list
       if(high==1){
           for(int i=0;i<width;i++){
               list.add(matrix[0][i]);
           }
           return list;
       }
       //如果只有一列,直接添加至list
       if(width==1){
           for(int j=0;j<high;j++){
               list.add(matrix[j][0]);
           }
           return list;
       }
       //将外面一圈添加至list
       for(int i=0;i<width;i++){
           list.add(matrix[0][i]);
       }
       for(int j=0;j<high-1;j++){
           list.add(matrix[j+1][width-1]);
       }
        for(int k=width-2;k>=0;k--){
           list.add(matrix[high-1][k]);
       }
        for(int t=high-2;t>0;t--){
           list.add(matrix[t][0]);
       }
       //如果行列数均大于2,内层二维数组递归调用
       if(high>2&&width>2){
          int arr[][]=new int[high-2][width-2];
          for(int i=0;i<high-2;i++){
              for(int j=0;j<width-2;j++){
                  arr[i][j]=matrix[i+1][j+1];
              }
          }
          printMatrix(arr);
       }
       return list;
    }
}


发表于 2020-03-30 17:51:49 回复(0)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        boolean flag1 = true;//为true时进行增,为false时减。
        boolean flag2 = true;//用于标记现在是更改i还是j;
        ArrayList<Integer> back = new ArrayList<>();
        int n = matrix.length;
        if(n == 0)return back;
        int m = matrix[0].length;
        if(m == 0)return back;
        System.out.println(n+"行"+m+"列");
        if(n==1 || m==1) {//只有一行或者一列
        	for(int k1=0;k1<n;k1++)
        		for(int k2 = 0;k2<m;k2++)
        			back.add(matrix[k1][k2]);
        	return back;
        }
        int i=0,j=0;
        //结束条件 back.size() == m*n
        int count = 0;
        int total = m*n;
        while(true){
            back.add(matrix[i][j]);
            if(flag1){//说明在增加索引
                if(flag2){
                    j++;//行不变,往右走
                    if(j==m-1){//走到本行最后了
                        flag2 = !flag2;
                    }
                }else{
                    i++;
                    if(i==n-1){//走到本列最后了
                        flag2 = !flag2;
                    }
                }
                if(i==n-1 && j==m-1){//说明走到右下角了,注意这里+1是因为之前更新过m和n
                	m--;n--;
                	System.out.println("我走到右下角了");
                    flag1 = !flag1;
                }
            }else{//开始减少索引
                if(flag2){
                    j--;
                    if(j==count) {
                    	flag2 = !flag2;
                    }
                }else{
                    i--;
                    if(i==count+1) {
                    	flag2 = !flag2;
                    }
                }
                if(j==count && i==count+1) {
                	System.out.println("我走到左上角了");
                	count++;
                	flag1 = !flag1;
                }
            }
            if(back.size()==total)break;
        }
        return back;
    }//end of func
}
....我真的写了一个顺时针。。。哎太多细节要考虑了,居然写了一晚上那么久。
最开始忽略了只有一行和只有一列的情况,感觉自己的办法思路很好理解,就是实现起来特别恶心,比较笨拙。但好歹通过了。
发表于 2020-03-26 00:52:19 回复(0)
基本思路是按左下右上四个方向打印,遇到边界就转弯,直到所有数据打印出来。

 public static ArrayList<Integer> printMatrix2(int[][] matrix) {
        if (matrix == null) return null;
        if (matrix[0] == null) return null;
        ArrayList<Integer> list = new ArrayList<>();
        int rows = 0;//记录输出
        int endColum = matrix.length - 1;//记录上下方向的结束位置
        int colum = 0;//记录输出
        int endRows = matrix[0].length - 1;//记录左右方向的结束位置
        int start = 0;//内层索引
        int end = 0;//外层索引
        int count = 0;//记录方向
        int size=matrix.length*matrix[0].length;
        while (true) {
                        //只剩一行或一列
            if (endRows == 0 || endColum == 0) {
                if (endColum == 0) {
                    while (list.size()<size) {
                        list.add(matrix[start][end++]);
                    }
                    return list;
                } else {
                    while (list.size()<size) {
                        list.add(matrix[start++][end]);
                    }
                    return list;
                }
            }
                        //从左到右
            if (count == 0) {
                list.add(matrix[start][end++]);
                rows++;
            }              
                       //从上到下
                        if (count == 1) {
                list.add(matrix[start++][end]);
                colum++;
            }
                        //从右到左
            if (count == 2) {
                list.add(matrix[start][end--]);
                rows++;
            }
                        //从下到上
            if (count == 3) {
                list.add(matrix[start--][end]);
                colum++;
            }
                        //转换方向
            if (rows == endRows || colum == endColum) {
                rows = 0;
                colum = 0;
                count++;
                                //每转四次为一轮
                if (count == 4) {
                    end = ++start;
                    count = 0;
                    endRows = endRows - 2;
                    endColum = endColum - 2;
                }
            }
            if (list.size() ==size) return list;
        }
    }




编辑于 2020-03-25 22:51:40 回复(0)
import java.util.ArrayList;
public class Solution {
    private ArrayList<Integer> result=new ArrayList<>();
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        if(matrix==null || matrix.length==0)
            return null;
        int rows=matrix.length;
        int cols=matrix[0].length;
        int start=0;
        //找出每一圈的起始点。即左上角的点,(0,0) (1,1)等
        while(rows>start*2 && cols>start*2){
            int endCol=cols-1-start;//该次遍历时最右边列的坐标
            int endRow=rows-1-start;//该次遍历时最下边行的坐标

            for(int i=start;i<=endCol;++i){//打印第一行
                result.add(matrix[start][i]);
            }
            if(start<endRow){//满足才有一列可以打印,否则一行直接打印完毕
                for(int i=start+1;i<=endRow;++i){//打印最后一列
                    result.add(matrix[i][endCol]);
                }
            }
            if(start<endCol && start<endRow){//满足才有最后一行可以打印
                for(int i=endCol-1;i>=start;--i){//打印最后一行
                    result.add(matrix[endRow][i]);
                }
            }
            if(start<endCol && start< endRow-1){
                for(int i=endRow-1;i>start;--i){//打印第一列
                    result.add(matrix[i][start]);
                }
            }
            start++;
        }
        return result;
    }

}
发表于 2020-03-23 13:11:57 回复(0)
每次打印矩阵最外一圈,设置起始坐标与终止坐标(左上与右下),列出最终终止的特殊情况即可。
import java.util.ArrayList;
public class Solution {
    private ArrayList<Integer> roundList=new ArrayList<Integer>();
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        int[] leftTop={0,0};
        int[] rightBottom={matrix.length-1,matrix[0].length-1};
        printRound(leftTop,rightBottom,matrix);
        return roundList;
    }
    //每次调用该函数即从左上的起始坐标到右下的种植坐标输出一圈
    private void printRound(int[] leftTop, int[] rightBottom, int[][]matrix){
        //起始点坐标大于终止点坐标,完成输出;
        if(leftTop[0]>rightBottom[0]||leftTop[1]>rightBottom[1]){
            return;
        }
        //起始坐标与终止坐标重合,即为最后一个点
        if(leftTop[0]==rightBottom[0]&&leftTop[1]==rightBottom[1]){
            roundList.add(matrix[leftTop[0]][leftTop[1]]);
            return;
        }
        //两坐标同一列
        else if(leftTop[1]==rightBottom[1]){
            for(int i=leftTop[0];i<=rightBottom[0];i++){
                roundList.add(matrix[i][leftTop[1]]);
            }
            return;
        }
        //两坐标同一行
        else if (leftTop[0]==rightBottom[0]){
            for(int i=leftTop[1];i<=rightBottom[1];i++){
                roundList.add(matrix[leftTop[0]][i]);
            }
            return;
        }
        //正常情况,输出一圈结束
        else{
            for(int i=leftTop[1];i<=rightBottom[1];i++){
                roundList.add(matrix[leftTop[0]][i]);
            }
            for(int i=leftTop[0]+1;i<rightBottom[0];i++){
                roundList.add(matrix[i][rightBottom[1]]);
            }
            for(int i=rightBottom[1];i>=leftTop[1];i--){
                roundList.add(matrix[rightBottom[0]][i]);
            }
            for(int i=rightBottom[0]-1;i>leftTop[0];i--){
                roundList.add(matrix[i][leftTop[1]]);
            }
            leftTop[0]++;
            leftTop[1]++;
            rightBottom[0]--;
            rightBottom[1]--;
            printRound(leftTop,rightBottom,matrix);
        }
    }
}


发表于 2020-03-23 12:49:33 回复(0)
方法: 使用状态机思想,即定义四个打印方向,然后做好状态转移:
enum Direction{
    up,down,left,right
}
// 19.顺时针打印矩阵
public ArrayList<Integer> printMatrix(int [][] matrix) {
    ArrayList<Integer> ans=new ArrayList<>();
    if(matrix==null||matrix.length==0||matrix[0].length==0) return ans;
    int m=matrix.length,n=matrix[0].length;
    int i=0,j=0;
    boolean[][] vis=new boolean[m][n];
    Direction d=Direction.right;
    //状态机方法,注意顺时针的状态转换: right -> down -> left -> up -> right
    while(ans.size()!=m*n){
        //            System.out.println(i+", "+j);
        if(d.equals(Direction.right)){
            if(j<n&&!vis[i][j]){
                vis[i][j]=true;
                ans.add(matrix[i][j++]);
            }else{//状态转移并回退(因为越界了或者重复访问)
                --j;
                ++i;
                d=Direction.down;
            }
        }else if(d.equals(Direction.down)){
            if(i<m&&!vis[i][j]){
                vis[i][j]=true;
                ans.add(matrix[i++][j]);
            }else{
                --i;
                --j;
                d=Direction.left;
            }
        }else if(d.equals(Direction.left)){
            if(j>=0&&!vis[i][j]){
                vis[i][j]=true;
                ans.add(matrix[i][j--]);
            }else{
                ++j;
                --i;
                d=Direction.up;
            }
        }else if(d.equals(Direction.up)){
            if(i>=0&&!vis[i][j]){
                vis[i][j]=true;
                ans.add(matrix[i--][j]);
            }else{
                ++i;
                ++j;
                d=Direction.right;
            }
        }
    }
    return ans;
}


编辑于 2020-03-15 23:52:22 回复(0)

一圈一圈循环就是干,注意边界和特殊情况就行

        public ArrayList printMatrix(int [][] matrix) {
            //方法1:迭代
            ArrayList res=new ArrayList();
            int row=matrix.length-1,col=matrix[0].length-1;
            int rs=0,re=row,cs=0,ce=col;
            while (rs<re&&cs<ce){
                //cs——ce,rs行
                for (int i=cs;i<ce;++i)
                    res.add(matrix[rs][i]);
                for (int i=rs;i<re;++i)
                    res.add(matrix[i][ce]);
                for (int i=ce;i>cs;--i)
                    res.add(matrix[re][i]);
                for (int i=re;i>rs;--i)
                    res.add(matrix[i][cs]);
                ++rs;--re;++cs;--ce;
            }
            if (rs==re){
                for (int i=cs;i<=ce;++i)
                    res.add(matrix[rs][i]);
            }else if (cs==ce){
                for (int i=rs;i<=re;++i)
                    res.add(matrix[i][cs]);
            }
            return res;
        }
发表于 2020-03-13 09:21:25 回复(0)