zoukankan      html  css  js  c++  java
  • [LeetCode]面试题29.顺时针打印矩阵

    解法一

    解法一通过模拟运动路径打印矩阵,通过判断下个位置是否越界、下个位置是否已访问来控制顺时针旋转。判断元数位置是否已经访问需要用到一个辅助数组visited,每访问一个位置就把visited对应位置进行标记。

    java

    class Solution {
        public int[] spiralOrder(int[][] matrix) {
            if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
                return new int[0];
            }
            int[] ans = new int[matrix.length * matrix[0].length];
            int rows = matrix.length;//矩阵的行数
            int cols = matrix[0].length;//矩阵的列数
            int total = rows * cols;//矩阵的总元数个数
            boolean[][] visited = new boolean[rows][cols];//定义一个辅助数组用于记录该位置是否被访问过
            int row = 0, col = 0;//一开始从左上角开始
            int[][] directions = {{0,1},{1,0},{0,-1},{-1,0}};//方向数组用于控制row与col移动
            int directionIndex = 0;//用于方向切换默认向右移动
            for(int i = 0; i < total; i++){
                ans[i] = matrix[row][col];
                visited[row][col] = true;//标记辅助数组表示该位置已经访问过
                int nextRow = row + directions[directionIndex][0];//nextRow,nextCol用于指定下一个位置判断越界、
                int nextCol = col + directions[directionIndex][1];//和访问的情况
                if(nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols || visited[nextRow][nextCol]){
                    //出现越界或者下个位置的元数已访问的情况就切换方向
                    directionIndex = (directionIndex + 1)%4;
                }
                row += directions[directionIndex][0];
                col += directions[directionIndex][1];
            }
            return ans;
        }
    }
    

    解法二

    解法二通过按层模拟来打印矩阵,每次按照顺时针的顺序打印最外层,使用top、bottom、left、right来标记矩阵最外层位置。

    1. 初始化top、bottom、left、right为矩阵最外层

    2. 先遍历最外层顶侧从 ( t o p , l e f t ) (top, left) (top,left) ( t o p , r i g h t ) (top, right) (top,right)

    3. 再遍历最外层右侧从 ( t o p + 1 , r i g h t ) (top+1, right) (top+1,right) ( b o t t o m , r i g h t ) (bottom, right) (bottom,right)

    4. 如果 l e f t < r i g h t 且 t o p < b o t t o m left<right 且top < bottom left<righttop<bottom时才能遍历底侧与左侧

      • ( b o t t o m , r i g h t − 1 ) (bottom, right-1) (bottom,right1) ( b o t t o m , l e f t ) (bottom, left) (bottom,left)
      • ( b o t t o m − 1 , l e f t ) (bottom-1, left) (bottom1,left) ( t o p + 1 , l e f t ) (top+1, left) (top+1,left)
    5. 更新为下一层
      top++;
      bottom–;
      left++;
      right–;

    java

    class Solution {
        public int[] spiralOrder(int[][] matrix) {
            if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
                return new int[0];
            }
            int[] ans = new int[matrix.length * matrix[0].length];
            int rows = matrix.length;//矩阵的行数
            int cols = matrix[0].length;//矩阵的列数
            int left = 0, top = 0, right = cols - 1, bottom = rows - 1;
            int index = 0;
            while(top <= bottom && left <= right){
                //顶侧和右侧是肯定需要遍历的
                for(int col = left; col <= right; col++){//遍历最外层顶侧
                    ans[index++] = matrix[top][col];
                }
                for(int row = top+1; row <= bottom; row++){//遍历最外层右侧
                    ans[index++] = matrix[row][right];
                }
                //left < right时从右往左遍历才有意义,如果left = right,说明最内层矩阵只有一列,上面两步已经将最外层遍历过了,
                //top < bottom时从底部往上遍历才有意义,如果top = bottom,说明最内层矩阵只有一行, 上面两步已经将最外层遍历过了
                if(left < right && top < bottom){
                    for(int col = right-1; col >= left; col--){//从右往左遍历
                        ans[index++] =  matrix[bottom][col];
                    }
                    for(int row = bottom -1; row > top; row--){//从下往上遍历
                        ans[index++] =  matrix[row][left];
                    }
                }
                //更新为下一层
                top++;
                bottom--;
                left++;
                right--;
            }
            return ans;
        }
    }
    
  • 相关阅读:
    数据结构与算法20170804
    设计模式之抽象工厂模式20170803
    设计模式之建造者模式20170802
    设计模式之工厂方法模式20170801
    设计模式之中介者模式20170731
    设计模式之门面模式20170728
    设计模式之适配器模式20170727
    设计模式之装饰模式20170726
    AndroidStudio 开发JNI
    NDK开发: 打印C代码的调试信息Log
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13860034.html
Copyright © 2011-2022 走看看