问题描述:

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix:

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

You should return [1,2,3,6,9,8,7,4,5].

算法:

递归算法,像那首洋葱歌里唱的:  如果你愿意一层一层一层的剥开我的心 你会鼻酸你会流泪 只要你能听到我 看到我的全心全意  
。。。。。
选择level变量表示层数,target矩阵表示元素是否被访问过,访问过为1,否则为0


class Solution(object):
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """
        row = len(matrix)
        if row == 0:
            return []
        col = len(matrix[0])
        target = [[0 for _ in range(col)] for _ in range(row)]     # 不能使用 [[0]*col]*row 因为其他行的列表都是对第一行的列表的引用
        level = 0
        path = []
        return self.gener_path((0,0), target, matrix, level, path)
        
    def gener_path(self, start, target, matrix, level, path):
        r,c = start
        if self.isNoWay(r,c,target):
            return path
        row = len(matrix)
        col = len(matrix[0])
        # up line
        for col_idx in range(c,col-level):
            path.append(matrix[r][col_idx])
            target[r][col_idx] = 1
        r,c = r+1, col_idx
        
        if self.isNoWay(r,c,target):
            return path
        # right line
        for rol_idx in range(r, row-level):
            path.append(matrix[rol_idx][c])
            target[rol_idx][c] = 1
        r, c = rol_idx, c-1
        if self.isNoWay(r,c,target):
            return path
        # down line
        for col_idx in range(c, level-1, -1):
            path.append(matrix[r][col_idx])
            target[r][col_idx] = 1
        r,c = r-1, col_idx
        if self.isNoWay(r,c,target):
            return path
        # left line
        for row_idx in range(r, level, -1):
            path.append(matrix[row_idx][c])
            target[r][col_idx] = 1
        r,c = row_idx, c+1
        level += 1
        return self.gener_path((r,c), target, matrix, level, path)
        
    def isNoWay(self, r, c, target):
        if r>=len(target) or r <0:
            return True
        if c>=len(target[0]) or c<0:
            return True
        return target[r][c] == 1
对于Python中矩阵的构造,推荐使用列表推导式。

如果使用注释中的方法往往陷入如下陷阱:

import pprint
d = [[0]*9]*8
pprint.pprint(d)
d[0][0] = 1
d[0][1] = 2
d[0][2] = 3
pprint.pprint(d)
结果为:

[[0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0]]
[[1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0],
 [1, 2, 3, 0, 0, 0, 0, 0, 0]]

:)