給定一個字串,用鋸齒狀重新排列並重組後回傳,鋸齒可任意調整大小。
https://leetcode.com/problems/zigzag-conversion/
範例Input: s = "PAYPALISHIRING", numRows = 4Output: "PINALSIGYAHRPI"Explanation:P I NA L S I GY A H RP I
範例是重新排序為 4 列的鋸齒狀,
從第 1 列開始由左到右取出字元重組。最後回傳重組後的PIN + ALSIG + YAHR + PI 即為答案。
能發現鋸齒走向是一個個的循環,看範例第 1 列的 P 、 I 、 N,中間都是 6 的 loop 。
而下一個字母循環 A 、 S 、 G 也是,不過這邊要注意的是中間穿插了 L 跟 I ,
但其實 L 、 I 亦是同樣的循環,因此我們第 2 列只要抓出 A 跟 L 後再交錯循環下去即可。
寫成程式的概念大概是
第二列s[0+1] + s[6-1] + s[(0+1)+6] + s[(6-1)+6] + ...A L
第 3 列以後也是相同的概念,直到第 4 列的轉角,又回到了單一元素的循環,至此所有的字母都重新組合完成。
我們將上述步驟用代數替換掉,即為我們的程式碼
public static String convert(String s, int numRows) {
//如果不轉角,值接回傳原字串
if (numRows == 1) {
return s;
}
//本次的循環的跳號數
int loop = numRows + numRows - 2;
char[] schar = s.toCharArray();
StringBuilder ans = new StringBuilder();
//首字母的循環
for (int n = 0; n < s.length(); n = n + loop) {
ans.append(schar[n]);
}
int m = 1;
//進行中段的交錯循環,若m == loop - m表示已碰到轉角
while (m != loop - m) {
//交錯循環中,第一個字母各別的位置
int i = m;
int j = loop - m;
while (i < s.length() || j < s.length()) {
if (i < s.length()) {
ans.append(schar[i]);
i = i + loop;
}
if (j < s.length()) {
ans.append(schar[j]);
j = j + loop;
}
}
m++;
}
//轉角字母的循環
for (int n = numRows - 1; n < s.length(); n = n + loop) {
ans.append(schar[n]);
}
return ans.toString();
}
沒有留言:
張貼留言