About
LeetCode刷題第7天,經(jīng)過這幾天的預(yù)熱,腦子活絡(luò)起來了,做題速度有了很大的提升,今天這道題為一道中等難度的題,花費了我近1小時,雖然時間還是很長,但是相對剛接觸LeetCode有了很大的提升,我會繼續(xù)堅持。
字符串Z形變換
題目描述
將一個給定字符串根據(jù)給定的行數(shù),以從上往下、從左到右進(jìn)行 Z 字形排列。
比如輸入字符串為 "LEETCODEISHIRING" 行數(shù)為 3 時,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的輸出需要從左往右逐行讀取,產(chǎn)生出一個新的字符串,比如:"LCIRETOESIIGEDHN"。
請你實現(xiàn)這個將字符串進(jìn)行指定行數(shù)變換的函數(shù):
string convert(string s, int numRows);
示例 1:
輸入: s = "LEETCODEISHIRING", numRows = 3
輸出: "LCIRETOESIIGEDHN"
示例 2:
輸入: s = "LEETCODEISHIRING", numRows = 4
輸出: "LDREOEIIECIHNTSG"
解釋:
L D R
E O E I I
E C I H N
T S G
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/zigzag-conversion
解題思路
以前在牛客網(wǎng)上刷到一道順時針打印二維數(shù)組的題,跟這個比較類似,我認(rèn)為做這類題都是要找到它的周期以及周期的規(guī)律,這樣我們就可以使用循環(huán)結(jié)構(gòu)解題了~
-
拿到題后,我先自己畫了畫,找到其中一種周期如下圖所示:
周期.jpeg - 找到周期后分析周期規(guī)律為:操作行數(shù)的順序為2,1,0,1,2,3 。一個周期的操作次數(shù)為(numRows -1)*2。
- 將一個周期分為兩部分,前半部分的規(guī)律是隨著index增加行數(shù)減小,后半部分隨著index增加行數(shù)增加。
- 在while循環(huán)中嵌套for循環(huán),因為字符串的長度不一定能夠整除numRows,所以for循環(huán)中可能會出現(xiàn)list out of range的錯誤,一旦出現(xiàn)該錯誤就說明字符串已經(jīng)遍歷完畢了。
- 字符串遍歷完畢后,調(diào)用將二維列表轉(zhuǎn)成字符串的方法返回結(jié)果。
代碼如下(Python3)
class Solution:
def assemble(self, array):
result = ''
for item in array:
result += ''.join(i for i in item)
return result
def convert(self, s: str, numRows: int) -> str:
if numRows <= 0:
return False
elif numRows == 1:
return s
if len(s) <= numRows:
return s
s = list(s)
result = [ [s.pop(0)] for item in range(numRows)]
while len(s):
for i in range((numRows - 1) * 2):
for j in range(numRows - 1):
try:
result[numRows-2 - j].append(s.pop(0))
except BaseException:
return self.assemble(result)
for k in range(numRows - 1):
try:
result[k + 1].append(s.pop(0))
except BaseException:
return self.assemble(result)
return self.assemble(result)
解法2
上面那種解法只是該類題的一種通解,運用在這道題上明顯太麻煩,如果我們用一個指針指向需要被操作的行數(shù),我們會發(fā)現(xiàn)行數(shù)的變化規(guī)律為:行數(shù)從0開始自增到最大行數(shù)-1然后開始自減到0,依次循環(huán),所以我們可以通過一個指針指向需要備操作的行數(shù),然后往里面追加字符,代碼如下:
#-*- coding:utf-8 -*-
#Author: Bing Xu
class Solution:
def convert(self, s: str, numRows: int) -> str:
if numRows <= 0:
return False
elif numRows == 1:
return s
length = len(s)
if length <= numRows:
return s
temp = ['' for i in range(numRows)]
index = 0
i = 0
while index < length:
while index < length and i < numRows - 1 :
temp[i] += s[index]
index += 1
i += 1
while index < length and i > 0:
temp[i] += s[index]
index += 1
i -= 1
result = ''.join(str(item) for item in temp)
return result
運行結(jié)果

image.png
解法3
其實我們也可以根據(jù)字符串字符的index直接算出來它歸屬于哪一行,但是其實時間復(fù)雜度不會變,并且我們還是需要一個新的列表去記錄,對內(nèi)存的消耗也不會減少,所以我沒有用代碼實現(xiàn)這種算法,只是一種思維的拓寬吧。
結(jié)束語
看到博客的小伙伴給我點個贊吧,每日更新哦~
