LeetCode:字符串Z形變換

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)解題了~

  1. 拿到題后,我先自己畫了畫,找到其中一種周期如下圖所示:


    周期.jpeg
  2. 找到周期后分析周期規(guī)律為:操作行數(shù)的順序為2,1,0,1,2,3 。一個周期的操作次數(shù)為(numRows -1)*2。
  3. 將一個周期分為兩部分,前半部分的規(guī)律是隨著index增加行數(shù)減小,后半部分隨著index增加行數(shù)增加。
  4. 在while循環(huán)中嵌套for循環(huán),因為字符串的長度不一定能夠整除numRows,所以for循環(huán)中可能會出現(xiàn)list out of range的錯誤,一旦出現(xiàn)該錯誤就說明字符串已經(jīng)遍歷完畢了。
  5. 字符串遍歷完畢后,調(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é)束語

看到博客的小伙伴給我點個贊吧,每日更新哦~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容