LeetCode 6. 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 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"
.
一道medium的题目,说实话还是卡了我不少时间,题目的意思不难理解,一个字符串按照锯齿形写入,按照行读出,输出读出 的字符串即可,关键是需要找出规律,先来看一个例子:
比如有一个字符串 “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
我们注意到第一行和最后一行相邻数字间隔为2*nRows - 2,并且这两行中没有中间锯齿上的数字(红色部分),处理起来比较简单。除去首尾两行,中间的部分需要找规律,主要中间每行中,相邻的黑色数字相差也为2*nRows - 2,红色数字在原来字符串中的编号为 j + 2*nRows - 2 - 2*i ,其中j 则为每个红色数字在这一行中前一个黑色数字的列数。找到规律之后代码就比较好写了,完整代码如下:
1 class Solution { 2 public: 3 //自己想了一下,挺有意思的一道题,终于理解是咋回事了 4 string convert(string s, int nRows) { 5 if (nRows <= 0) 6 return string(""); 7 if (nRows == 1) 8 return s; 9 string res = ""; 10 int size = 2 * nRows - 2; 11 for (int i = 0; i < nRows; i++) 12 { 13 for (int j = i; j < s.length(); j += size) 14 { 15 res += s[j]; 16 int tmp = j + size - 2 * i; 17 if (i != 0 && i != nRows - 1 && tmp < s.length()) //既不是最后一行也不是第一行,并且也没有超过总长度 18 res += s[tmp]; 19 } 20 } 21 return res; 22 } 23 };
部分内容参考: