剑指 Offer 29. 顺时针打印矩阵(54. 螺旋矩阵)
题目:
思路:
【1】使用辅助变量,和构建使用的偏移数据组合,然后在单次循环中对数据进行塞入
【2】不使用辅助空间,按照模拟的思维,使用四个变量记录范围值,然后按照逻辑遍历塞入数组,其中需要特殊处理的便是最后形成一行或一列的情况。
代码展示:
使用辅助变量进行单循环:
//时间3 ms击败20.1% //内存43 MB击败88.20% 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; boolean[][] visited = new boolean[rows][columns]; int total = rows * columns; int[] order = new int[total]; int row = 0, column = 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]; visited[row][column] = true; int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1]; 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 ms击败100% //内存39.6 MB击败47.71% //时间复杂度:O(mn),其中 m 和 n 分别是输入矩阵的行数和列数。矩阵中的每个元素都要被访问一次。 //空间复杂度:O(1)。除了输出数组以外,空间复杂度是常数。 class Solution { public List<Integer> spiralOrder(int[][] matrix) { List<Integer> order = new ArrayList<Integer>(); if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return order; } int rows = matrix.length, columns = matrix[0].length; int left = 0, right = columns - 1, top = 0, bottom = rows - 1; while (left <= right && top <= bottom) { for (int column = left; column <= right; column++) { order.add(matrix[top][column]); } for (int row = top + 1; row <= bottom; row++) { order.add(matrix[row][right]); } if (left < right && top < bottom) { for (int column = right - 1; column > left; column--) { order.add(matrix[bottom][column]); } for (int row = bottom; row > top; row--) { order.add(matrix[row][left]); } } left++; right--; top++; bottom--; } return order; } } //时间1 ms击败61.99% //内存43.4 MB击败44.85% class Solution { public int[] spiralOrder(int[][] matrix) { if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return new int[]{}; } int index=0; int rows = matrix.length, columns = matrix[0].length; int[] order = new int[rows*columns]; int left = 0, right = columns - 1, top = 0, bottom = rows - 1; while (left <= right && top <= bottom) { for (int column = left; column <= right; column++) { order[index++] = matrix[top][column]; } for (int row = top + 1; row <= bottom; row++) { order[index++] = matrix[row][right]; } if (left < right && top < bottom) { for (int column = right - 1; column > left; column--) { order[index++] = matrix[bottom][column]; } for (int row = bottom; row > top; row--) { order[index++] = matrix[row][left]; } } left++; right--; top++; bottom--; } return order; } }