1. 程式人生 > >Leetcode:ZigZag Conversion

Leetcode:ZigZag Conversion

end lap eat ++ 有效 ges ide -1 pen

問題的大意就是將字符串中的字符按鋸齒狀(倒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 }
View Code

Leetcode:ZigZag Conversion