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 {View Code7 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