劍指offer-順時針打印矩陣(python和c++)

題目描述

輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字,例如,如果輸入如下4 X 4矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

思路來自

在這裏插入圖片描述
首先拿到這個題,讀完題我們腦子裏會呈現出這樣的一個畫面。從外圈到內圈順序的依次打印,我們就可以把矩陣想象成若干個圈,如上圖所示,我們可以用一個循環來打印矩陣,每一次打印矩陣中的一個圈。那麼循環結束的條件是什麼?假設這個矩陣的行數是rows,列數是columns。打印第一圈的左上角的座標是(0, 0),第二圈的左上角的座標是(1, 1),依次類推。我們注意到左上角的座標中行標和列標總是相同的,於是可以在矩陣中選取左上角爲(start,start)的一圈作爲我們的分析的目標。

對於一個5*5的矩陣,最後一圈只有一個數字,對應的座標爲(2, 2)。5 > 2 * 2;

對於一個6*6的矩陣,最後一圈有4個數字,其左上角的座標仍是(2, 2)。6 > 2 *2;

故循環繼續的條件爲columns > startX * 2並且rows > startY * 2。

打印一圈的實現可以分爲4步:第一步從左到右打印一行,第二步從上到下打印一列,第三步從右到左打印一行,第四步從下到上打印一列(每一步根據起始座標和終止座標用一個循環就能打印出一行或者一列)。

在這裏插入圖片描述
注意:最後一圈可能退化成只有一行、只有一列,甚至只有一個數字,因此打印這樣的一圈就不再需要四步,可能只需要三步、兩步、一步。

接下來我們分析打印時每一步的前提條件。第一步總是需要的,因爲打印一圈至少有一步。如果只有一行,那麼就不用第二步了。即第二步的前提條件是終止行號大於起始行號。打印第三步的前提條件是圈內至少有兩行兩列。即除了要求終止行號大於起始行號外,還需要終止列號大於起始列號。同理打印第四步的前提條件是至少有三行兩列,即要求終止行號比起始行號至少大2,同時終止列號大於起始列號。

寫的非常好的一個解釋,這道題之前也放了很久,每次看到就不想做,終於啃下來了。下面給出python和c++的實現。

python

# -*- coding:utf-8 -*-
class Solution:
    # matrix類型爲二維列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if matrix==None:
            return
        rows = len(matrix)
        cols = len(matrix[0])
        start = 0
        result = []
        while rows > 2*start and cols > 2*start:
            endx = rows - 1 - start
            endy = cols - 1 - start
            for i in range(start, endy+1):
                result.append(matrix[start][i])
            if start < endx:
                for i in range(start+1,endx+1):
                    result.append(matrix[i][endy])
            if start < endx and start < endy:
                for i in range(endy-1, start-1, -1):
                    result.append(matrix[endx][i])
            if start < endx-1 and start < endy:
                for i in range(endx-1, start, -1):
                    result.append(matrix[i][start])
            start += 1
        return result

c++

class Solution {
public:
    vector<int> printMatrix(vector<vector<int>> matrix) {
        int row=matrix.size();
        int col=matrix[0].size();
        vector<int> result;
        if(row==0||col==0)
            return result;
        int left=0,right=col-1,top=0,btm=row-1;
        while(left<=right&&top<=btm)
            {
            for(int i=left;i<=right;i++)
                result.push_back(matrix[top][i]);
            if(top<btm)
                for(int i=top+1;i<=btm;i++)
                    result.push_back(matrix[i][right]);
            if(top<btm&&left<right)
                for(int i=right-1;i>=left;i--)
                    result.push_back(matrix[btm][i]);
            if(top+1<btm&&left<right)
                for(int i=btm-1;i>=top+1;i--)
                    result.push_back(matrix[i][left]);
            left++;right--;top++;btm--;
        }
        return result;
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章