layout: post
title: 19 - Clockwise Printing Matrix
category: sword finger offer
tags:
description:
Title Description
Input a matrix and print out each number in clockwise order from outside to inside. For example, if you input the following 4X 4 matrix: 1 23 4 5 6 7 8 9 11 12 13 14 15 16, print out the numbers 1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10.
Matrix A, Part I (0, 1,...) of M*N The four coordinate sequences of the circle are A[i][i... N-2-i] and A [i... M-2-i][N-1-i] and A[M-1-i][N-1-i... i+1] and A[M-1-i... i+1][i], remember that it's a closed interval.
For each sequence, if it does not exist, print stops. The conditions for its non-existence are I > N-2-i, I > M-2-i, N-1-i < i+1, M-1-i < i+1, respectively. Take the first circle as an example to illustrate the printing rules for each circle, which are N-1, M-1, N-1 and M-1 in turn.
However, the code implemented according to the above idea is not feasible, and the number will be omitted, such as for 3 *33 times 33 3 or 3 *53 times 53 5 matrices. The analysis shows that four coordinate sequences sometimes fail to capture a number.
class Solution: # matrix type is a two-dimensional list, which needs to be returned def printMatrix(self, matrix): if matrix is None or len(matrix) == 0 or len(matrix[0]) == 0: return None M,N = len(matrix),len(matrix[0]) i = -1 numlist = [] while True: i += 1 if i <= N-2-i: numlist.extend(matrix[i][i:N-2-i+1]) else: if len(numlist) == M*N: break if i <= M-2-i: for j in range(i,M-2-i+1): # Two-dimensional arrays cannot slice elements in different rows in the same column, so each element needs to be accessed one by one. numlist.append(matrix[j][N-1-i]) else: if len(numlist) == M*N: break if N-1-i>=i+1: numlist.extend(matrix[M-1-i][N-1-i:i+1-1:-1]) else: if len(numlist) == M*N: break if M-1-i >= i+1: for j in range(M-1-i,i+1-1,-1): numlist.append(matrix[j][i]) else: if len(numlist) == M*N: break return numlist
Firstly, we calculate the number of circles (min(M,N)+1)//2. Secondly, we set the stop condition of printing, that is, when the number of numbers printed is equal to the number of numbers M*N contained in the matrix, then we print N, M-1, N-1 and M-2 in turn, which means greedy algorithm.
class Solution: # matrix type is a two-dimensional list, which needs to be returned def printMatrix(self, matrix): # write code here M,N = len(matrix), len(matrix[0]) if M < 1 or N < 1: return None elif M == 1 and N == 1: return [matrix[0][0]] res = [] for o in range((min(M,N)+1)//2): res.extend([matrix[o][n] for n in range(o, N-o)]) if len(res) == M*N: # Determine if the printing has finished break res.extend([matrix[m][N-1-o] for m in range(o+1, M-o)]) if len(res) == M*N: break res.extend([matrix[M-1-o][n] for n in range(o, N-o-1)[::-1]]) if len(res) == M*N: break res.extend([matrix[m][o] for m in range(o+1, M-o-1)[::-1]]) if len(res) == M*N: break return res
Matters needing attention:
- The above M,N = len(matrix), len(matrix[0]) is not well written, there will be matrix or matrix[0] is not a list, there will be exceptions. Change to
if matrix is None or len(matrix) == 0 or len(matrix[0]) == 0:return None, according to short-circuit operation rules, program exceptions can be avoided.