offer 29 顺时针打印矩阵

顺时针打印矩阵

image.png

题目解答

一圈一圈往内层走

由题目咱们能够发现规律,就是一圈一圈往里走,那么每一圈都是以左上角[0,0]为顶点开始走,而后走一圈到左上角下面那个点就走完了,而后开始下一圈就是[1,1],而后开始新的一圈
image.png
image.png数组

  • 因此咱们给定上下左右边界,top,down,left,right,初始top=0,down = matrix.length-1,left = 0,right = matrix[0].length-1,给定好以后先按照边界走,当走完一圈left+1,right-1,top+1,down-1,为边界继续走
  • class Solution {
      public int[] spiralOrder(int[][] matrix) {
          //首先判断矩阵不为空
          if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
              return new int[0];
          }
          //矩阵不为空,就先定义一个和他长度同样的数组
          int i_len = matrix.length;
          int j_len = matrix[0].length;
          int[] array= new int[i_len*j_len];
          int index = 0;//定义新的一维数组的索引点
          //找规律 要先定义上下左右边界 不可以超出
          int top = 0;int down = i_len-1; int left = 0;int right = j_len-1; 
          //定义最后返回的条件走完全部圈以后 两个边界能够重,但不能小,由于小了就说明已经错行了
          while(left<=right&&top<=down){
              //上面的行索引完毕
              for(int i = left;i<=right;i++){
                  array[index++] = matrix[top][i];
              }
              //右侧列索引 上面那个for已经包括了右上角那个点
              for(int j = top+1;j<=down;j++){
                  array[index++] = matrix[j][right];
              }
              //下面的行索引 上面那个for已经包括了右下角的点
              //判断条件不能等于,若是等于当列比行多的时候就会走这个循环多加值了
              //就是下来走的行仍是前面的相同那行
              //因此要判断此时的right和left top down 
              //若是有两个值是相同的那说明就生下了一行或者一列 在上面的行和列就已经走完了
              //若是两个值都不相等也不大于,那就说明还有圈 继续走
              if(left<right&&top<down){
                  for(int k = right-1;k>left;k--){
                      array[index++] = matrix[down][k];
                  }
              //左侧列索引 
                  for(int m = down;m>top;m--){
                      array[index++] = matrix[m][left];
                  }
              }
          
              left++;
              top++;
              right--;
              down--;
          }
          return array;
      }
    }

    注意
    //下面的行索引 上面那个for已经包括了右下角的点
    //判断条件不能等于,若是等于当列比行多的时候就会走这个循环多加值了
    //就是下来走的行仍是前面的相同那行
    //因此要判断此时的right和left top down
    //若是有两个值是相同的那说明就生下了一行或者一列 在上面的行和列就已经走完了
    //若是两个值都不相等也不大于,那就说明还有圈 继续走
    image.pngspa

模拟打印矩阵的路径

  • 初始位置是矩阵的左上角,初始方向是向右,当路径超出界限或者进入以前访问过的位置时,顺时针旋转,进入下一个方向。
  • 添加一个辅助矩阵,将走过的元素的索引设为已经访问过true false
  • 判断路径结束了就是矩阵中全部元素都被访问了,也就是路径的长度达到矩阵中的元素数量的时候就是完整的路径
  • class Solution {
      public int[] spiralOrder(int[][] matrix) {
          //判断输入的矩阵不为空
          if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
              return new int[0];
          }
          int rows = matrix.length, columns = matrix[0].length;
          //定义一个辅助矩阵,表征是否访问过此位置的元素 默认值是false
          boolean[][] visited = new boolean[rows][columns];
          int total = rows * columns;
          int[] order = new int[total];
          int row = 0, column = 0;
          //定义四个方向数组,不一样方向到时候选不一样的数组  
          //当前行列分别加0,1就是往右走
          //当前行列分别加1,0就是往下走
          //当前行列分别加0,-1就是往左走
          //当前行列分别加-1,0就是往上走
          int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
          int directionIndex = 0;
          for (int i = 0; i < total; i++) {
              //当前点的值加入新矩阵
              order[i] = matrix[row][column];
              //访问过当前点 当前点位置在辅助矩阵置为true
              visited[row][column] = true;
              //下一个点的坐标
              int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
              //判断下一个点是否是越界或者已经访问过
              //下一个索引点本应该到达拐点的下一个点(角顶点的下一个)的时候,发现上面那个nextrow仍是在原来的基础上再同一方向走了一个点,走完以后就超出索引了,因此此时就应该拐弯了,而后根据directionIndex+1.来走下一方向,若是此时directionIndex=3,再+1,后面就directionIndex变成0,就说明前面一圈走完了,就进入下一圈
              //或者下一个点已经访问过了那就换方向,若是上下左右四个方向都访问过了,那就说明是最后一个点,就结束了
              if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) {
                  directionIndex = (directionIndex + 1) % 4;
              }
              //判断没有不知足题目,就找到下一个真的索引
              row += directions[directionIndex][0];
              column += directions[directionIndex][1];
          }
          return order;
      }
    }

    这个逻辑思惟厉害了
    image.pngcode