題目
將一個給定字符串根據(jù)給定的行數(shù)财岔,以從上往下风皿、從左到右進(jìn)行 Z 字形排列。
比如輸入字符串為 "LEETCODEISHIRING" 行數(shù)為 3 時匠璧,排列如下:
L C I R
E T O E S I I G
E D H N
之后桐款,你的輸出需要從左往右逐行讀取,產(chǎn)生出一個新的字符串夷恍,比如:"LCIRETOESIIGEDHN"魔眨。
請你實(shí)現(xiàn)這個將字符串進(jìn)行指定行數(shù)變換的函數(shù):
string convert(string s, int numRows);
示例 1:
輸入: s = "LEETCODEISHIRING", numRows = 3
輸出: "LCIRETOESIIGEDHN"
示例 2:
輸入: s = "LEETCODEISHIRING", numRows = 4
輸出: "LDREOEIIECIHNTSG"
解釋:
L D R
E O E I I
E C I H N
T S G
解題思路
- 對字符串進(jìn)行分組
- 根據(jù)行數(shù)計(jì)算出每一組字符串?dāng)?shù)
- 同樣根據(jù)行數(shù)和字符串?dāng)?shù)計(jì)算出Z字形變換的列數(shù)
- 新建一個字符串,迭代遍歷Z字形的每一個元素酿雪,判斷是否存在字符遏暴,如果存在計(jì)算出該位置原來的字符串的索引,追加到新的字符串指黎。
值得注意的是Swift字符串訪問元素效率很低朋凉,可以轉(zhuǎn)換成Character數(shù)組,效率是原來的3倍醋安。
Swift代碼
class Solution {
func convert(_ s: String, _ numRows: Int) -> String {
if s.isEmpty || numRows <= 1 {
return s
}
var array = s.map({$0})
let groupCount = 2 * numRows - 2
let columnPerGroup = numRows - 1
var numColumns = columnPerGroup * (array.count / groupCount)
let remainder = array.count % groupCount
numColumns += (remainder / numRows) + (remainder % numRows)
var string = ""
for y in 0..<numRows {
for x in 0..<numColumns {
var i = 0
let groupIndex = x / columnPerGroup
let groupRemainder = x % columnPerGroup
if groupRemainder == 0 {
i = groupCount * groupIndex + y
if i < array.count {
string.append(array[i])
}
} else {
if groupRemainder + y + 1 == numRows {
i = groupCount * groupIndex + (groupCount - y)
if i < array.count {
string.append(array[i])
}
}
}
}
}
return string
}
}