题目描述

  • 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字
  • 例如,如果输入如下矩阵:
    • 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

解析

  • 因为每打印一圈都会改变起始坐标,所以需要先确定矩阵大小与起始坐标的关系

  • 比如4阶矩阵,第一圈起始坐标为(0,0),第二圈起始坐标为(1,1),打印两圈之后就结束了

  • 比如一个5阶矩阵,前两圈同4阶,第三圈为(2,2),而且只打印了一个数。
  • 会发现,只要起始坐标的两倍小于阶数,就会一直转圈打印
  • 所以停止转圈打印的条件就是起始坐标的2倍大于或者等于阶数

  • 然后考虑每一圈的打印方法

  • 第一步:从左到右打印一行

  • 第二步:从上到下打印一列(需满足终止行号大于起始行号)
  • 第三步:从右到左打印一列(需满足终止行号大于起始行号的同时,终止列号大于起始列号)
  • 第四步:从下到上打印一列(需满足终止行号比起始行号大2,终止列号大于起始列号)
  • 注意:打印矩阵最里面一圈可能只需要三步、两步、甚至一步

代码实现

  1. public ArrayList<Integer> printMatrix(int [][] matrix) {
  2. if(matrix == null || matrix.length <= 0 || matrix[0].length <= 0){
  3. return null;
  4. }
  5. ArrayList<Integer> list = new ArrayList<Integer>();
  6. int rows = matrix.length;
  7. int cols = matrix[0].length;
  8. //起点坐标
  9. int start = 0;
  10. while(rows > 2 * start && cols > 2 * start){
  11. printMatrixInCircle(list,matrix,rows,cols,start);
  12. start++;
  13. }
  14. return list;
  15. }
  16. /**
  17. * 打印每一圈
  18. * @param list 返回的集合
  19. * @param matrix 矩阵
  20. * @param rows 行数
  21. * @param cols 列数
  22. * @param start 起点坐标
  23. */
  24. private void printMatrixInCircle(ArrayList<Integer> list, int[][] matrix, int rows, int cols, int start) {
  25. //endX为终止行号,endY为终止列号
  26. int endX = rows - start - 1;
  27. int endY = cols - start - 1;
  28. //从左到右的一行
  29. for(int i = start; i <= endY; i++){
  30. list.add(matrix[start][i]);
  31. }
  32. //从上到下的一行
  33. if(endX > start){
  34. for(int i = start + 1; i <= endX; i++){
  35. list.add(matrix[i][endY]);
  36. }
  37. }
  38. //从右到左的一行
  39. if(endX > start && endY > start){
  40. for(int i = endY - 1; i >= start; i--){
  41. list.add(matrix[endX][i]);
  42. }
  43. }
  44. //从下到上的一行
  45. if(endX - 1 > start && endY > start){
  46. for(int i = endX - 1; i >= start + 1; i--){
  47. list.add(matrix[i][start]);
  48. }
  49. }
  50. }