剑指 Offer 29. 顺时针打印矩阵
- 题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
- 解法一:参考剑指offer书上解法,模拟顺时针回归过程
如图,打印一圈的过程可以分解为4个分步骤:从左往右,从上往下,从右往左,从下往上
1.首先可以将每次顺时针旋转的一圈的左上角和右下角坐标找到,将左上角坐标设为(start,start),设矩阵行数为rows,列数为columns,因此,打印一圈的条件的是colums>2*start,rows>2*start。
2.对于打印一圈的4个步骤,有的情况不一定全部包含4个步骤,因此在进行每个步骤的时候,需要判断
判断条件:
a) 从左往右,始终需要
b) 从上往下,起始行号<终止行号
c) 从右往左,起始行号<终止行号,起始列号<终止列号
d) 从下往上,起始列号<终止行号,起始列号<终止列号-1
class Solution: def spiralOrder(self, matrix): if not matrix: return columns = len(matrix[0]) #列数 rows = len(matrix) #行数 start = 0 printList = [] def PrintMatrixInCircle(matrix, columns, rows, start): alist = [] endx = columns - start - 1 #打印总列数 endy = rows - start - 1 #打印总行数 #从左往右打印 for i in range(start,endx+1): alist.append(matrix[start][i]) #从上往下打印 if start < endy: for i in range(start+1, endy+1): alist.append(matrix[i][endx]) #从右往左打印 if start < endx and start < endy: for i in range(endx-1, start-1, -1): alist.append(matrix[endy][i]) #从下往上打印 if start < endx and start < endy - 1: for i in range(endy-1, start, -1): alist.append(matrix[i][start]) return alist while columns > start * 2 and rows > start * 2: printList += PrintMatrixInCircle(matrix, columns, rows, start) start += 1 return printList
- 解法二:参考题解,设定边界
设定打印的左右上下边界为:l,r,t,b。从左往右打印,则t+1,r-1此时需要判断t<b,否则跳出打印,同理上往下,从右向左,从下往上均是。
def spiralOrder(self, matrix): if not matrix:return [] l, r, t, b, res = 0, len(matrix[0])-1, 0, len(matrix)-1, [] while True: for i in range(l, r+1): res.append(matrix[t][i]) t += 1 if t > b:break for i in range(t, b+1): res.append(matrix[i][r]) r -= 1 if r < l:break for i in range(r, l-1, -1): res.append(matrix[b][i]) b -= 1 if b < t:break for i in range(b, t-1, -1): res.append(matrix[i][l]) l += 1 if l > r:break return res