參考鏈接
http://blog.csdn.net/zhouworld16/article/details/14121477
http://blog.csdn.net/doc_sgl/article/details/12099217
題目描述
ZigZag Conversion
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 RAnd 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"
.題目分析
題目要求:
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"
.
所謂的ZigZag,就是這樣的:(P.S:某些瀏覽器的高速模式可能看不到圖,兼容或IE模式應該可以)
因爲這是有規律的,可以用數學公式計算出下一個數組下標,這樣節省了一定的空間和時間。 題目的輸出是按行來拼接字符的,
因此我們可以通過逐行計算下標,拼接字符來達到目的。
通過畫圖觀察,我們可以發現,
第0行和最後一行中,前一個下標的值和後一個下標的值相差 2 * nRows - 2 ,以第0行爲例,前一個下標爲0,
後一個下標爲 0+2*4-2=6。
中間行中,前一個下標的值和後一個下標的值需要根據這個下標是該行中的奇數列還是偶數列來計算。以平時的習慣
來計算,因此,行和列的開始值都是0。
以第2行爲例,第一個下標是2,後一個下標所處列爲1,是奇數列,因此從這個下標到下一個下標相差的值是它們所處
的行i下面的所有行的點的個數,即2 * (nRows - 1 - i)。在這裏,nRows-1是爲了遵循0下標開始的原則。這樣,我們可以
求得這個奇數列的下標爲 2+2*(4-1-2)=4。同理,當我們要計算4之後的下標時,我們發現下一個所處的是偶數列2,從這個
下標到下一個下標相差的值其實是它們所處的行i上面的所有行的點的個數,即2 * i。因此,該列的下標計算爲4+2*2=8。
有了以上的公式,我們就可以寫出代碼了。但需要注意幾點:
1.判斷所求出的下標是不是越界了,即不能超出原字串的長度;
2.注意處理nRows=1的情況,因爲它會使差值2 * nRows - 2的值爲0,這樣下標值會一直不變,進入死循環,產生
Memory Limit Exceeded 或者 Output Limit Exceeded之類的錯誤。
3.還有一些其他的邊界情況,如:nRows > s.length,s.length = 0等需要處理。
注意了以上事項後,就可以安全通過了。
以下是我的代碼,歡迎各位大牛指導交流~
總結
代碼示例
#if 1
class Solution {
public:
string convert(string s, int nRows) {
if(s == "" || nRows < 2) return s;
string ret;
int i = 0;
for(i=0;i<nRows&&i<s.size();i++)
{
int index = i;
ret += s[index];//////////////////////////////////////////////
for(int k=1; index < s.size();k++)
{
if(i == 0 || i == nRows-1)
{
index += 2*nRows-2;
}
else
{
if((k&0x01))
index += (nRows-i-1)*2;
else
index += 2*i;
}
if(index<s.size())
{
ret += s[index];
}
}
}
return ret;
}
};
#elif 1
class Solution {
public:
string convert(string s, int nRows) {
if(s == "" || nRows < 2) return s;
vector<string > vecstr(nRows,"");
int i = 0;
while(i<s.size())
{
for(int r = 0;r<nRows&&i<s.size();r++)
{
vecstr[r] += s[i++];
}
for(int r = nRows-2;r>0&&i<s.size();r--)
{
vecstr[r] += s[i++];
}
}
string ret = "";
for(int r = 0;r<nRows;r++)
{
ret += vecstr[r];
}
return ret;
}
};
#endif