LeetCode 6 蛇形矩陣,一道簡單的模擬題

點擊上方藍字,和我一起學技術。

題意

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) https://leetcode.com/problems/zigzag-conversion/

翻譯

給定一個字符串,將它變成蛇形輸出。這個蛇形的概念比較抽象,我們需要結合樣例才能理解。

樣例

P   A   H   N  A P L S I I G  Y   I   R  And then read line by line: "PAHNAPLSIIGYIR"    Write the code that will take a string and make this conversion given a number of rows:    string convert(string s, int numRows);  Example 1:    Input: s = "PAYPALISHIRING", numRows = 3  Output: "PAHNAPLSIIGYIR"  Example 2:    Input: s = "PAYPALISHIRING", numRows = 4  Output: "PINALSIGYAHRPI"  Explanation:    P     I    N  A   L S  I G  Y A   H R  P     I

分析

這題的題意有點鬼畜,意思是說將給定的字符串先按照蛇形排列好,然後再按行依次讀入,最後輸出新的字符串。

雖然LeetCode上給這題的難度是Medium,但實際上它還是比較簡單的。和上一題的曼切斯特算法比起來,算得上是很簡單的了。LeetCode 5 迅速判斷迴文串的曼切斯特算法

這題會告訴我們字符串以及蛇形扭曲的行數,將字符串排成蛇形。這種沒有任何算法或者數據結構,僅僅是實現題意的問題稱為模擬題。顯然今天的這一題就是一道模擬題。模擬題唯一的難度就是編碼,實現一些比較複雜的功能,考驗的其實是工程能力。

這個蛇形的排列也很簡單,因為我們只要輸出最後的按行連接的結果。所以我們完全可以忽略列的位置信息,只用關注擺放的行就好了。因為行數是有限的,對於每一行,我們可以用一個字符串記錄當前行目前為止擺放的字符串,最後按照行的順序將所有行的結果連接到一起就好了。通過觀察,我們很容易發現,擺放的行是有周期規律的。一個周期是2 * rowJum – 2,從0先遞增到rowNum – 1,再遞減到1。

發現規律之後,再寫出code就不難了。

def convert(text, numRows):      # 記錄每一行結果的dict      lines = {}      if numRows == 0:          return text        for i in range(len(text)):          # 計算應該放在哪一行          idx = i % (2 * numRows - 2)          # 判斷是在遞增區間還是遞減區間          if idx >= numRows:              idx = 2 * numRows - 2 - idx            line = lines.get(idx, "")          lines[numRows] = line + text[i]        result = ""      # 拼接答案      for i in range(numRows):          result += lines[i]      return result

上面的代碼很簡單,但是藏着一個可以優化的地方。

在於dict的使用,dict的查詢需要開銷。其實我們可以替換成數組,因為我們已經確定行數了,所以數組的長度是固定的。如此優化之後,時間效率會更高一點。但是差別不會很大,代碼就不放了,我想大家應該都能想明白。

今天的文章就到這裡,如果覺得有所收穫,請點個在看或者轉發吧。