基於Python實現對字符串的Z形轉換
1、題目描述
將字符串 "PAYPALISHIRING"
以Z字形排列成給定的行數:
P A H N
A P L S I I G
Y I R
之後從左往右,逐行讀取字符:"PAHNAPLSIIGYIR"
示例 1:
輸入: s = "PAYPALISHIRING", numRows = 3
輸出: "PAHNAPLSIIGYIR"
示例 2:
輸入: s = "PAYPALISHIRING", numRows = 4
輸出: "PINALSIGYAHRPI"
解釋:
P I N
A L S I G
Y A H R
P I
2、算法設計
首先觀察Z形轉換的規律,轉換的規則如下所示:
如上圖所示,是按照箭頭指示方向排列字符串的,其中數字代表字符串的索引。
算法一:可以通過暴力解算,即建立一個足夠大的二維數組,將按照規則轉換的Z形數據存放到二維數組中,然後按照行順序讀取。
算法二:按照Z形排列的規律,直接在字符串上讀取對應索引的元素即可。在這裏採取第二種算法。算法具體原理如下:
通過觀察,可得到下圖所示的規律:、
如上圖所示,在Z形數據中中,每一行的兩個Z的邊界之間的距離爲6,在此設n1和n2兩個變量,其中n1表示Z形中左邊部分的距離,n2表示Z形中右邊部分的距離,則n1+n2 = 6;通過觀察還會發現,兩個Z形數據的邊界之間的距離6其實是行數相關的,即zlen = 2*(numRows-1),經證明,該公示是正確的! 通過觀察發現,其中n1是numRows和i相關的,n1 = 2*(numRows-i-1)。
而對於第i行的數據(其中i爲字符串s中的第i個元素,i<numRows),後邊的數據都和i相關,即index = i; index = index+n1或者index = index + n2,而n1+n2 = zlen。
3、最終實現
算法的最終實現如下所示:
def convert(self, s, numRows):
if numRows <= 1:
return s
k = len(s)
rstr = ""
zlen = 2 * (numRows - 1) #求zlen, 即Z形數據的邊界
for i in range(0, numRows):
n1 = 2 * (numRows-i-1) #計算n1
n2 = zlen - n1 #計算n2
if n1 == 0 or n2 == 0:
n1 = n2 = zlen
j = 1
index = i
while index < k:
rstr = rstr + s[index]
if j % 2 != 0:
index = index + n1
else:
index = index + n2
j += 1
return rstr
該算法的平均耗時120ms。