Leetcode6 Z字形變換

2021-08-31 18:43:14 字數 1724 閱讀 1425

給定乙個字串,找出不含有重複字元的最長子串的長度。

示例 1:

輸入: s = "paypalishiring", numrows = 3

輸出: "pahnaplsiigyir"

解釋:p a h n

a p l s i i g

y i r

示例 2:

輸入: s = "paypalishiring", numrows = 4輸出: "pinalsigyahrpi"

解釋:p i n

a l s i g

y a h r

p i

這道題有兩種解法,一種是利用數學表示式計算出行數與元素排布位置的聯絡,用數學表示式表達出,不過這並不是我們想要的最優解,或者說,他並不優雅,因為沒有體現出演算法的美感,只是單純的找規律了。

所以我們想,能不能不靠找規律,準備乙個陣列與之對應:

通過從左向右迭代字串,我們可以輕鬆地確定字元位於 z 字形圖案中的哪一行。

我們可以使用min

(numrows

,len(s

))

\text( \text, \text(s))

min(

numrows

,len(s

))個列表來表示 z 字形圖案中的非空行。

從左到右迭代 ss,將每個字元新增到合適的行。可以使用當前行和當前方向這兩個變數對合適的行進行跟蹤。

只有當我們向上移動到最上面的行或向下移動到最下面的行時,當前方向才會發生改變。

class

solution

string ret;

for(string row : rows) ret += row;

return ret;}}

;

"paypalishiring"numrows=3為例:

我們首先把行數,元素數兩者最小那個當做劃分區域(通常都是行數小),這樣我們就分成了numrows=3組,很自然,我們把前三個元素依次放到,第1、2、3組中,注意,當我們觸底(currows=3)時,需要回溯(減小currows),所以我們建立了變數goingdown,來控制是向上還是向下。

而且只需要遍歷一次,下面以goingdown的改變來分組

依次類推,很容易明白其中規律

其實數學規律很容易想到,但是**可能可能不是很容易寫出來,但是上面的這種演算法,很直觀,為什麼不容易想到呢,我認為是思維受到了限制,我們很容易地就直接造出乙個與原陣列等長的陣列,乙個乙個往上去新增,但是我們可以先靠行分類,然後改變量值放入的順序。

本體值得注意的有

vectorrows(min(numrows, int(s.size())));

··· rows[currow] += c;

vector中的元素型別是string,這一點很巧妙,這樣只需要乙個加號,就能在結尾新增新字元。

goingdown = !goingdown;

currow += goingdown ? 1 : -1;

能把**寫到如此簡潔需要乙個過程,當然,簡單點的話可以寫乙個判斷來改變goingdown的值

最重要的思想還是通過控制currow的步進方向,來實現z字形變換

讓我們一起進步啊

LeetCode 6 Z字形變換

將字串 paypalishiring 以z字形排列成給定的行數 p a h n a p l s i i g y i r之後從左往右,逐行讀取字元 pahnaplsiigyir 實現乙個將字串進行指定行數變換的函式 string convert string s,int numrows 輸入 s pa...

leetcode 6 Z字形變換

將字串 paypalishiring 以z字形排列成給定的行數 p a h n a p l s i i g y i r之後從左往右,逐行讀取字元 pahnaplsiigyir 實現乙個將字串進行指定行數變換的函式 string convert string s,int numrows 示例 1 輸入...

LeetCode 6 Z字形變換

把整個問題拆解為 儲存 取 的兩個過程 通過觀察我發現的是,當numrows為3時,兩列之間的數字的數目為1 當numrows為4時,兩列之間的數字的數目為2,以此類推。那麼,可不可以將每一列都存起來 col 兩列之間的數字也存起來 gap 最後要輸出時再通過遍歷的方式拼接出結果呢?以題目中給的字串...