题目:
给出一个字符串,将字符串按照顺序排成歪“Z”型,然后横向按行读出。
举例:
ABCDEFGHIJKLMNOPQRSYUVWXYZ,numRow = 4:
A G M S Y
B F H L N R T X Z
C E I K O Q U W
D G P V
最终读出的结果就是AGMSYBFHNRTXZCEIKOQUWDGPV
行数就是就是numRow,numRow == 5时,读出的结果是AIQYBHJPRXZCGKOSWDFLNTVEMU
思路:
这样的排列看上去是很有规律的,只要搞清楚之间的规律,并用公式的形式表现出来,那么问题就可以迎刃而解。
就以上面的举例为例子说明:
首先int i = 0,i为行号,从0带numRow-1即4,对于第一行和最后一行,每两个字母之间的间距是6。即A往后数6个字母就是G,G往后数6个字母就是M,观察numRow等于不同值的情况发现,第一行和最后一行的两个字母之间的间距是2*(numRow - 1)。
接下来看其他行,首先观察第二行,i=1,B和F之间的间距为4,F和H之间的间距为2,加起来为6,而这正是第一行字母的间距,这是很显然,相当于字母都往后推进了一个,即A-G和B-H之间的关系。那么我们可以先将B加进去,然后加F和H,然后加L和N。通过找规律可以发现F和B之间的距离,L和H之间的距离为(numRow - i - 1)*2,F和H之间的距离,L和N之间的距离为2*i。
根据上面找到的规律我们就可以把代码完成了。
代码:
public class ZigZag_Conversion {
public static String convert(String s, int numRows)
{
int length = s.length();
if(numRows >= length || numRows == 1)
return s;
String s1 = "";
for(int i = 0;i < numRows;i++)
{
int line_row = i;
int k = 0;
while(true)
{
if(line_row > length - 1)
break;
s1 += s.charAt(line_row);
if(i == 0 || i == numRows - 1)
line_row += 2*(numRows - 1);
else
{
if(k % 2 == 0){line_row += 2 * (numRows - i - 1);k = 1;}
else{line_row += i * 2; k = 0;}
}
}
}
return s1;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(convert("ABCDEFGHIGKLMNOPQRSTUVWXYZ",5));
}
}
时间复杂度:
虽然程序中出现了一个嵌套循环,但是显然处理的字符只有输入字符串的个数n,所以时间复杂度为O(n)。
空间复杂度:
要将输入字符串复制一份,所以空间复杂度为O(n)。