19-Clockwise Printing Matrix

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.

Posted by bentobenji on Thu, 03 Oct 2019 18:41:45 -0700