classSolution{ public List<Integer> spiralOrder(int[][] matrix){ List ans = new ArrayList(); if (matrix.length == 0) return ans; int R = matrix.length, C = matrix[0].length; boolean[][] seen = newboolean[R][C]; int[] dr = {0, 1, 0, -1}; int[] dc = {1, 0, -1, 0}; int r = 0, c = 0, di = 0; for (int i = 0; i < R * C; i++) { ans.add(matrix[r][c]); seen[r][c] = true; int cr = r + dr[di]; int cc = c + dc[di]; if (0 <= cr && cr < R && 0 <= cc && cc < C && !seen[cr][cc]){ r = cr; c = cc; } else { di = (di + 1) % 4; r += dr[di]; c += dc[di]; } } return ans; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution(object): defspiralOrder(self, matrix): ifnot matrix: return [] R, C = len(matrix), len(matrix[0]) seen = [[False] * C for _ in matrix] ans = [] dr = [0, 1, 0, -1] dc = [1, 0, -1, 0] r = c = di = 0 for _ in range(R * C): ans.append(matrix[r][c]) seen[r][c] = True cr, cc = r + dr[di], c + dc[di] if0 <= cr < R and0 <= cc < C andnot seen[cr][cc]: r, c = cr, cc else: di = (di + 1) % 4 r, c = r + dr[di], c + dc[di] return ans
复杂度分析
时间复杂度: O(N),其中 N 是输入矩阵所有元素的个数。因为我们将矩阵中的每个元素都添加进答案里。
空间复杂度: O(N),需要两个矩阵 seen 和 ans 存储所需信息。
方法 2:按层模拟
直觉
答案是最外层所有元素按照顺时针顺序输出,其次是次外层,以此类推。
算法
我们定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。例如,下图矩阵最外层元素都是第 1 层,次外层元素都是第 2 层,然后是第 3 层的。
classSolution{ public List < Integer > spiralOrder(int[][] matrix) { List ans = new ArrayList(); if (matrix.length == 0) return ans; int r1 = 0, r2 = matrix.length - 1; int c1 = 0, c2 = matrix[0].length - 1; while (r1 <= r2 && c1 <= c2) { for (int c = c1; c <= c2; c++) ans.add(matrix[r1][c]); for (int r = r1 + 1; r <= r2; r++) ans.add(matrix[r][c2]); if (r1 < r2 && c1 < c2) { for (int c = c2 - 1; c > c1; c--) ans.add(matrix[r2][c]); for (int r = r2; r > r1; r--) ans.add(matrix[r][c1]); } r1++; r2--; c1++; c2--; } return ans; } }
复杂度分析
时间复杂度: O(N),其中 N 是输入矩阵所有元素的个数。因为我们将矩阵中的每个元素都添加进答案里。
publicstaticvoidmain(String[] args){ // Scanner in = new Scanner(System.in); // int n = in.nextInt(); // in.close(); int[][] matrix = newint[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; List<Integer> list = spiralOrder(matrix); System.out.println(list); }
static List<Integer> spiralOrder(int[][] matrix){ List<Integer> list = new ArrayList<>(); if (matrix.length == 0) return list; int u = 0, d = matrix.length - 1, l = 0, r = matrix[0].length - 1; while (true) { // 向右 for (int i = l; i <= r; i++) list.add(matrix[u][i]); if (++u > d) break; // 向下 for (int i = u; i <= d; i++) list.add(matrix[i][r]); if (--r < l) break; // 向左 for (int i = r; i >= l; i--) list.add(matrix[d][i]); if (--d < u) break; // 向上 for (int i = d; i >= u; i--) list.add(matrix[i][l]); if (++l > r) break; } return list; }
classSolution{ public List<List<Integer>> generate(int numRows) { List<List<Integer>> triangle = new ArrayList<List<Integer>>();
// First base case; if user requests zero rows, they get zero rows. if (numRows == 0) { return triangle; }
// Second base case; first row is always [1]. triangle.add(new ArrayList<>()); triangle.get(0).add(1);
for (int rowNum = 1; rowNum < numRows; rowNum++) { List<Integer> row = new ArrayList<>(); List<Integer> prevRow = triangle.get(rowNum-1);
// The first row element is always 1. row.add(1);
// Each triangle element (other than the first and last of each row) // is equal to the sum of the elements above-and-to-the-left and // above-and-to-the-right. for (int j = 1; j < rowNum; j++) { row.add(prevRow.get(j-1) + prevRow.get(j)); }
for row_num in range(num_rows): # The first and last row elements are always 1. row = [Nonefor _ in range(row_num+1)] row[0], row[-1] = 1, 1
# Each triangle element is equal to the sum of the elements # above-and-to-the-left and above-and-to-the-right. for j in range(1, len(row)-1): row[j] = triangle[row_num-1][j-1] + triangle[row_num-1][j]