这道题的时间复杂度是O(N), 空间复杂度也是O(N)
这道题也是matrix的遍历,只是遍历的顺序是sprial,这种题的模版就是写出变化的delta,然后check新的点是不是在matrix的范围内,加上其他条件,这道题的条件是是否已经visit过,当满足就会发生一些变化,比如方向的变化。还有一个小的tip是如何循环delta,就是用次数除以变化取余数。eg. x%4
class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: if not matrix: return [] n_row, n_col = len(matrix), len(matrix[0]) result = [] visited = [[False for i in range(n_col)] for j in range(n_row)] row, col, x = 0, 0, 0 delta = [[0,1], [1, 0], [0, -1], [-1, 0]] for _ in range(n_row * n_col): result.append(matrix[row][col]) visited[row][col] = True new_row = row + delta[x % 4][0] new_col = col + delta[x % 4][1] if self.will_change_direction(new_row, new_col, visited): x += 1 row += delta[x % 4][0] col += delta[x % 4][1] return result def will_change_direction(self, row, col, visited): if row < 0 or row >= len(visited): return True if col < 0 or col >= len(visited[0]): return True if visited[row][col]: return True return False
这道题其实还有更好的空间解法,就是用四个变量,row_begin, row_end, col_begin, col_end,每次都要update这些值。leetcode上一个java的解法就是这样的,
public class Solution { public ListspiralOrder(int[][] matrix) { List res = new ArrayList (); if (matrix.length == 0) { return res; } int rowBegin = 0; int rowEnd = matrix.length-1; int colBegin = 0; int colEnd = matrix[0].length - 1; while (rowBegin <= rowEnd && colBegin <= colEnd) { // Traverse Right for (int j = colBegin; j <= colEnd; j ++) { res.add(matrix[rowBegin][j]); } rowBegin++; // Traverse Down for (int j = rowBegin; j <= rowEnd; j ++) { res.add(matrix[j][colEnd]); } colEnd--; if (rowBegin <= rowEnd) { // Traverse Left for (int j = colEnd; j >= colBegin; j --) { res.add(matrix[rowEnd][j]); } } rowEnd--; if (colBegin <= colEnd) { // Traver Up for (int j = rowEnd; j >= rowBegin; j --) { res.add(matrix[j][colBegin]); } } colBegin ++; } return res; } }