Medium!
題目描述:
將字符串 "PAYPALISHIRING"
以Z字形排列成給定的行數:(下面這樣的形狀)
P A H N A P L S I I G Y I R
之后按逐行順序依次排列:"PAHNAPLSIIGYIR"
實現一個將字符串進行指定行數的轉換的函數:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3)
應當返回 "PAHNAPLSIIGYIR"
。
題意解釋:
比如有一個字符串 “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
解題思路:
這道題就是看坐標的變化。並且需要分塊處理。
n=2時,字符串坐標變成zigzag的走法就是:
0 2 4 6
1 3 5 7
n=3時的走法是:
0 4 8
1 3 5 7 9
2 6 10
n=4時的走法是:
0 6 12
1 5 7 11 13
2 4 8 10 14
3 9 15
我們發現,除了第一行和最后一行沒有中間形成之字型的數字外,其他都有,而首位兩行中相鄰兩個元素的index之差跟行數是相關的,為 2*nRows - 2, 根據這個特點,我們可以按順序找到所有的黑色元素在元字符串的位置,將他們按順序加到新字符串里面。對於紅色元素出現的位置也是有規律的,每個紅色元素的位置為 j + 2*nRows-2 - 2*i, 其中,j為前一個黑色元素的列數,i為當前行數。 比如當n = 4中的那個紅色5,它的位置為 1 + 2*4-2 - 2*1 = 5,為原字符串的正確位置。當我們知道所有黑色元素和紅色元素位置的正確算法,我們就可以一次性的把它們按順序都加到新的字符串里面。代碼如下:
C++參考答案:
1 class Solution { 2 public: 3 string convert(string s, int nRows) { 4 if (nRows <= 1) return s; 5 string res = ""; 6 int size = 2 * nRows - 2; 7 for (int i = 0; i < nRows; ++i) { 8 for (int j = i; j < s.size(); j += size) { 9 res += s[j]; 10 int tmp = j + size - 2 * i; 11 if (i != 0 && i != nRows - 1 && tmp < s.size()) res += s[tmp]; 12 } 13 } 14 return res; 15 } 16 };