原题链接: https://leetcode.cn/problems/zigzag-conversion/
1.题目描述
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
2.题目分析
将题目意思将字符串的索引列出来, 分成3行展示出来
0, 4, 8, 12, 16,
1,3,5,7,9,11,13,15,17,
2, 6, 10, 14, 18,
分成4行展示,可以看出
0, 6, 12 18, 24,
1, 5,7, 11,13, 17,19, 23,
2,4, 8,10 14,16, 20,22,
3, 9, 15, 21,
从中可以找出规律,每(numRows+numRows-2) 个数据都可以划分为一部分;这一部分也可以分为两部分,如图所示 对余数进行判断
i%(2n-2) == 0 ----> row0
i%(2n-2) == 1 & 2n-2-1 ----> row1
i%(2n-2) == 2 & 2n-2-2 ----> row2
...
i%(2n-2) == n-1 ----> row(n-1)
==>
对 k = i%(2n-2)进行判断
k<=n-1时候,s[i]就属于第k行 k>n-1时候,s[i]就属于2n-2-k行 最后将rows拼接起来就行了
4.题目解析
class Solution {
fun convert(s: String, numRows: Int): String {
//排除非法输入
if(s.isEmpty() or (numRows < 1)) return s
if(s.length == 1 ) return s
if(numRows == 1) return s
val array = CharArray(s.length)
var ans = 0
val sbArray = Array<StringBuilder>(numRows){i->StringBuilder()}
s.forEachIndexed{index:Int,c:Char ->
ans = index % (2 * numRows - 2)
//遍历
if(ans <= numRows - 1){
sbArray[ans].append(c)
}
if(ans > numRows - 1){
sbArray[2 * numRows -2 -ans].append(c)
}
}
val result = StringBuilder()
for(i in 0 until numRows){
result.append(sbArray[i].toString())
}
return result.toString()
}
}