题意理解:
题目给出一个字符串和一个整数,如果将这个字符串列成之字形,那么按照从上到下再从左到右的顺序排列出来,对这个排列好的字符串,再重新按照从左到右再从上到下的顺序排列出来,得到一个新的字符串,返回它。
例如给出:
1 5
2 4 6 8
3 7
返回:15246837
思路分析:
1.我首先的想法,这个图形有变化和不变化的部分,需要把这些信息都获取到,就是通过整除和余数来得到相关的几个数据,来完全描述出这个图形长什么样,再进一步考虑的时候,发现这个方法需要大量的判断,和分别的循环,思路和实现都极其的负责而且低效。所以考虑,是否能够不去精准的描述出这个图形的形状(即得到几个关键描述数据),那么一定会有 i < s.size() 也即是说,不管最后图形收尾的时候是在哪一行,我们不需要知道,只需要对每一个处理的角标判断不大于s.size()即可。
2.接着开始思考规律性,规律往往是和循环相关联的,再思考循环里面的核心操作,是将s里面的元素放入一个新的string,我们就有了两个要操作的主体,因为要利用规律性,所以我们我们遍历s 从0到行数。(这是一个周期),我们肯定不应该再循环新的字符串,而直接应该一个一个的放入,或者关联它们的角标(第一者是可行的,因为我们的外层循环是一行一行的,我们得到的新的字符串也是放完前一行再放下一行)
3.大概考虑好了外层循环,我们再考虑内层(每一行),研究题目发现,第一行和最后一行是一类,其它是一类,对于竖直的那一列上的数字很好解决,在外层循环变量的基础上,以周期大小为增量增加就可以了,现在对于第二行到倒数第二行,它们还具有斜着的列上的数字,我们现在需要数学关联竖直列的角标和斜列的角标,进行一定的数学推断即可。
代码:
class Solution {
public:
string convert(string s, int numRows) {
if(s..size()<=1 || numRows <= 1)
return s;
string ret;
for(int i=0; i<numRows; i++)
{
for(int j=i; j < s.size(); j+=(numRows*2-2))
{
ret.push_back(s[j]);
if(i>0 && i<(numRows-1) && j+2*(numRows-1-i)<s.size())
ret.push_back(s[j+2*(numRows-1-i)]);
}
}
return ret;
}
};
另: java 实现 这个实现很棒https://discuss.leetcode.com/topic/47936/in-fact-this-is-a-math-problem-java-code/2