首页 > 代码库 > Leetcode:ZigZag Conversion
Leetcode:ZigZag Conversion
问题的大意就是将字符串中的字符按锯齿状(倒N形)垂直由上向下放置,最后水平从左向右读取。比如
ABCDEFGHIJKLMN,4表示
A G M
B F H L N
C E I K
D J
按水平顺序读取的结果则为AGMBFHLNCEIKDJ。(原题目的描述就很有问题)
解决方案非常简单,可以发现字符串中第i个字符,其水平右边最近的元素为i+2*(row-1),其中row为规定的行高。而除了第一行和最后一行,中间的行的处理逻辑是一致的,而首行和尾行的处理逻辑也是一致的。
res = ""
step = 2 * (row - 1)
//处理首行
for(int i = 0; i < s.length; i = i + step)
res = res + s[i]
//处理第1~row-2行
for(int i = 1; i< row - 1; i = i + 1)
//添加处于垂直列中的元素,如果有必要还要添加中间斜线上的元素
for(int j = i; j < s.length; j = j + step)
res = res + s[j]
if(j + step - i * 2 < s.length)
res = res + s[j + step - i * 2]
//处理尾行
for(int i = row - 1; i < s.length; i = i + step)
res = res + s[i]
由于每次循环体内的有效代码的执行都会将结果的长度增加1,但是结果的长度必定与s的长度一致,因此循环体最多只会执行s.length次,记n=s.length,因此这段代码的时间复杂度和空间复杂度均为O(n)。
最后惯例附上代码:
1 package cn.dalt.leetcode; 2 3 /** 4 * Created by dalt on 2017/6/9. 5 */ 6 public class ZigZagConversion { 7 public String convert(String s, int numRows) { 8 int slen = s.length(); 9 if (numRows == 1) { 10 return s; 11 } 12 StringBuilder sb = new StringBuilder(slen); 13 int totalstep = numRows + numRows - 2; 14 //The first line 15 for (int i = 0, bound = slen; i < bound; i += totalstep) { 16 sb.append(s.charAt(i)); 17 } 18 //The following line 19 for (int i = 1, iBound = numRows - 1; i < iBound; i++) { 20 int step = totalstep - i * 2; 21 for (int j = i, jBound = slen; j < jBound; j += totalstep) { 22 sb.append(s.charAt(j)); 23 if (j + step < jBound) { 24 sb.append(s.charAt(j + step)); 25 } 26 } 27 } 28 29 //The last line 30 for (int i = numRows - 1, iBound = slen; i < iBound; i += totalstep) { 31 sb.append(s.charAt(i)); 32 } 33 return sb.toString(); 34 } 35 }
Leetcode:ZigZag Conversion