关于java:offer-29-顺时针打印矩阵

38次阅读

共计 2700 个字符,预计需要花费 7 分钟才能阅读完成。

顺时针打印矩阵

题目解答

一圈一圈往内层走

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

  • 所以咱们给定上下左右边界,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
    // 如果有两个值是雷同的那阐明就生下了一行或者一列 在下面的行和列就曾经走完了
    // 如果两个值都不相等也不大于,那就阐明还有圈 持续走

模仿打印矩阵的门路

  • 初始地位是矩阵的左上角,初始方向是向右,当门路超出界线或者进入之前拜访过的地位时,顺时针旋转,进入下一个方向。
  • 增加一个辅助矩阵,将走过的元素的索引设为曾经拜访过 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;
      }
    }

    这个逻辑思维厉害了

正文完
 0