剑指offer—顺时针打印矩阵

题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
4*4矩阵
最后的输出是:
顺时针输出矩阵

思路

第一眼看到首先想到的肯定是算法书上的一道类似的题目,通过4个for循环来进行遍历。把每一圈都划分为一个子问题进行求解。但是问题是,如何确定每一个for循环的边界?一旦边界出现错误,就会有些数字没有进行输出,另一些数字反而重复输出。

函数:
 def output(self,result,matrix,n,size_one,size_two,count)

result是最后的输出列表。matrix是二维数组。n表示第几次调用这个函数,初始值是0。size_one表示本次调用的矩阵的行数。size_two表示本次调用的矩阵的列数。count表示最大需要调用多少次这个函数。

步骤

首先把最外圈首次调用函数看成n=0,也就是如图:
第一次调用函数
第一行看成第一个for循环的输出,此时是第一次遍历,n=0,输出的是array[0][0]到array[0][3]。其中最后一个输出的列是n+size_two-1。这也就确定了第一个for循环是从array[n][n]到array[n][n+size_two-1]。代码如下:

for i in range(0,size_two):
            result.append(matrix[n][n+i])

接着把最外圈的最后一列看成第二个for循环的输出,此时是第一次遍历,n=0,输出的是array[1][3]到array[3][3]。第一个输出是array[n+1][n+size_two-1]到array[n+size_one-1][n+size_two-1]。代码如下:

for i in range(n+1,n+size_one):
            result.append(matrix[i][n+size_two-1])

接着把最外圈的最后一行看成第三个for循环的输出,此时是第一次遍历,n=0,输出的是array[3][2]到array[3][0]。第一个输出是array[n+size_one-1][n+size_two-2]到array[n+size_one-1][n]。代码如下:

for i in range(2,size_two+1):         
                result.append(matrix[n+size_one-1][n+size_two-i])

接着把最外圈的第一列看成第四个for循环的输出,此时是第一次遍历,n=0,输出的是array[2][0]到array[1][0]。第一个输出是array[n+size_one-2][n]到array[n+1][n]。代码如下:

for i in range(2,size_one):         
                result.append(matrix[n+size_one-i][n])

然后我们就得到了上图中红色部分的输出。再调用一次这个函数,这个时候n=1。输出图中蓝色部分。
第二次调用函数的输出

这个时候调用函数时传进去的参数是

output(result,matrix,n+1,size_one-2,size_two-2,count)

需要注意的是因为每一次调用函数的输出是一圈,所以最后剩下的矩阵的大小是行数减少2,列数减少2。

问题

这个代码还有一个问题,就是如果输出到最后只剩下一行,或者只剩下一列,那么就会重复输出,所以我们必须要对后两个for循环进行约束,必须在行数和列数同时不为1的时候才进行后面两个for循环。

最后的函数代码:

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        result = []
        size_one = len(matrix)
        size_two = len(matrix[0])
        if size_one>size_two:
            if size_two%2==1:
                count = (size_two+1)/2
            else:
                count = size_two/2
        else:
            if size_one%2==1:
                count = (size_one+1)/2
            else:
                count = size_one/2
        self.output(result,matrix,0,size_one,size_two,count)
        return result

    def output(self,result,matrix,n,size_one,size_two,count):
        for i in range(0,size_two):
            result.append(matrix[n][n+i])
        for i in range(n+1,n+size_one):
            result.append(matrix[i][n+size_two-1])
        if n!=n+size_two-1 and n!=n+size_one-1:
            for i in range(2,size_two+1):         
                result.append(matrix[n+size_one-1][n+size_two-i])
            for i in range(2,size_one):                   ##
                result.append(matrix[n+size_one-i][n])
        if n+1<count:
            self.output(result,matrix,n+1,size_one-2,size_two-2,count)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章