題目描述
輸入一個矩陣均践,按照從外向里以順時針的順序依次打印出每一個數(shù)字,例如彤委,如果輸入如下4 X 4矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數(shù)字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
思路
如果我們一圈一圈的打印矩陣。
要解決的第一個問題是判斷什么時間終止循環(huán)焦影。假設每次打印從左上角開始车遂,對應的坐標為X,Y偷办。 因為每次打印橫向和豎向各有兩行,所以邊界的判斷是2X和2Y椒涯。將2X,2Y分別于行列的最大值比較,小于的話證明里面還有一圈可以打印狱意。
第二個問題是對于每一圈如何打印。這個問題可以成4個小問題拯欧,分別是
左->右:這一步是一定會執(zhí)行
上->下:這一步要保證終止行大約起始行,不然就是一行镐作,第一步就打印完了
右->左:保證當前打印的圈是2行2列起步,在上一步基礎(chǔ)上列號也要大于起始
下->上:至少3行2列该贾,終止行要比起始行大2.
這道題并沒有使用特殊的數(shù)據(jù)結(jié)構(gòu)或者算法,整體的思路就是分解問題杨蛋,把大問題分解成小問題。每個小問題解決之后整個問題就有解了逞力。
代碼
class Solution:
# matrix類型為二維列表曙寡,需要返回列表
def printMatrix(self, matrix):
# write code here
rows = len(matrix)
cols = len(matrix[0])
if matrix is None or rows<=0 or cols <=0 :
return None
start = 0
ans = []
while cols > 2*start and rows > 2*start:
result = self.circleMatrix(matrix,rows,cols,start)
ans.extend(result)
start = start+1
return ans
def circleMatrix(self,matrix,rows,cols,start):
endX = cols-1-start
endY = rows-1-start
result=[]
#left->right
for i in range(start,endX+1):
number = matrix[start][i]
result.append(number)
#up ->down
if start < endY:
for i in range(start+1,endY+1):
number = matrix[i][endX]
result.append(number)
#right -> left
if start < endY and start < endX:
for i in range(endX-1,start-1,-1):
number = matrix[endY][i]
result.append(number)
#down -> up
if start < endY-1 and start < endX:
for i in range(endY-1,start,-1):
number = matrix[i][start]
result.append(number)
return result
代碼中比較重要的部分是在circleMatrix這個方法里面举庶,里面主要是分4種情況討論了4步打印矩陣。這里再總結(jié)一下一些小細節(jié)揩抡,當做debug的總結(jié)。
首先捅膘,endX 和 endY 可以理解為當前要打印的矩陣的寬和高滚粟。
第一步,從左到右:
這里打印的長度就是當前矩陣的寬度凡壤。把當前一橫行的元素逐個打出來。
高度不變亚侠,寬度在移動曹体。所以坐標變化是[start][i] 其中i的范圍屬于:[start硝烂,endX]
第二步,從上到下:
當打印內(nèi)容只有一個或者一行時,第一步就打完了串稀。所以如果需要第二步的話,先置條件是行數(shù)要大于等于2 (endY - start >=1)母截。 在打印的時候,并不是打印這一整列清寇,因為這一列的第一個元素已經(jīng)作為第一步的最后一個元素打印出來了喘漏。如果起點不加一個华烟,會重復打印。所以坐標變換是[i][endX]垦江,i的范圍是[start+1,endY]。
第三步比吭,從右到左:
當滿足了前兩步的約束后,如果還需要第三步衩藤,那么情況至少是一個2行2列的矩陣吧慢。如果只是兩行的話赏表,兩步就打印完全部。 這里和第二步類似瓢剿,要注意有元素已經(jīng)在第二步打完了逢慌。所以起點需要向左挪一個间狂,從endX-1 開始。
第四部鉴象,從下到上:
需要第四步的話,矩陣的元素最少要有6個纺弊,也就是三行兩列。2行2列的情況在第三步就可以處理結(jié)束淆游。同樣需要注意的是地點要向上挪一個隔盛,從endY-1開始。