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)
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 text, int nRows);
convert("PAYPALISHIRING", 3)
should return "PAHNAPLSIIGYIR"
.
這道題剛開始看了半天沒看懂是咋樣變換的,上網查了些資料,終於搞懂了,就是要把字串擺成一個之字型的,參考了網上這位仁兄的解法 (http://www.cnblogs.com/springfor/p/3889414.html)。
比如有一個字串 “0123456789ABCDEF”,轉為zigzag
當 n = 2 時:
0 2 4 6 8 A C E
1 3 5 7 9 B D F
當 n = 3 時:
0 4 8 C
1 3 5 7 9 B D F
2 6 A E
當 n = 4 時:
0 6 C
1 5 7 B D
2 4 8 A E
3 9 F
我們發現,除了第一行和最後一行沒有中間形成之字型的數字外,其他都有,而首位兩行中相鄰兩個元素的index之差跟行數是相關的,為 2*nRows - 2, 根據這個特點,我們可以按順序找到所有的黑色元素在元字串的位置,將他們按順序加到新字串裡面。對於紅色元素出現的位置也是有規律的,每個紅色元素的位置為 j + 2*nRows-2 - 2*i, 其中,j為前一個黑色元素的列數,i為當前行數。 比如當n = 4中的那個紅色5,它的位置為 1 + 2*4-2 - 2*1 = 5,為原字串的正確位置。當我們知道所有黑色元素和紅色元素位置的正確演算法,我們就可以一次性的把它們按順序都加到新的字串裡面。程式碼如下:
class Solution { public: string convert(string s, int nRows) { if (nRows <= 1) return s; string res = ""; int size = 2 * nRows - 2; for (int i = 0; i < nRows; ++i) { for (int j = i; j < s.size(); j += size) { res += s[j]; int tmp = j + size - 2 * i; if (i != 0 && i != nRows - 1 && tmp < s.size()) res += s[tmp]; } } return res; } };
參考資料:
https://leetcode.com/problems/zigzag-conversion/description/