代码Gitee:https://gitee.com/xiaoyinhui/golang-code/tree/develop/test-beego/tests
6. Z 字形变换
题目:
func TestTitleIndex06(t *testing.T) {
// 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行Z 字形排列。
// 比如输入字符串为 "PAYPALISHIRING"行数为 3 时,排列如下:
// P A H N
// A P L S I I G
// Y I R
// 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
// 请你实现这个将字符串进行指定行数变换的函数:
// 示例1:
// 输入:s = "PAYPALISHIRING", numRows = 3
// 输出:"PAHNAPLSIIGYIR"
// 示例2:
// 输入:s = "PAYPALISHIRING", numRows = 4
// 输出:"PINALSIGYAHRPI"
// 解释:
// P I N
// A L S I G
// Y A H R
// P I
// 示例3;
// 输入:s = "A", numRows = 1
// 输出:"A"
// 来源:力扣(LeetCode)
// 链接:https://leetcode.cn/problems/zigzag-conversion
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
mStr := "PAYPALISHIRING"
fmt.Println("自己思路=", convert(mStr, 3))
fmt.Println("直接构造=", convert2(mStr, 3))
}
方法一:自己思路
第一次用手机撸,简直了
func convert(s string, numRows int) string {
if (numRows == 1) || (numRows >= len(s)) {
return s
}
mC := 0 // 列
mR := 0 // 行
mIsUp := true // true:从上往下添加字符 false:从下往往上添加字符
// 存放排序后的字符
mSlice := make([][]byte, numRows)
// 给每一行进行填充
for i := 0; i < numRows; i++ {
mSlice[i] = make([]byte, 0)
}
// 遍历字符串
for i := 0; i < len(s); i++ {
// 将遍历的当前字符添加到当前行列中
mSlice[mR] = append(mSlice[mR], s[i])
if mIsUp {
if mR >= numRows-1 {
mR--
mIsUp = !mIsUp
mC++
} else {
mR++
}
} else {
if mR <= 0 {
mR++
mIsUp = !mIsUp
} else {
mC++
mR--
}
}
}
mStr := ""
for _, a := range mSlice {
for _, mValue := range a {
mStr += string(mValue)
}
}
return mStr
}
方法二:官方题解 直接构造
func convert2(s string, numRows int) string {
// 可以从题目和示例2的解释发现,一条竖线+斜线(不算头尾) 可以看成一轮周期
// 一轮周期字符数 = numRows + (numRows - 2) ==> numRows*2 - 2
// 可知总轮数 = StrLen / 一轮周期字符数 【向上取整】
mStrLen := len(s)
if (numRows == 1) || (numRows >= mStrLen) {
return s
}
// 一轮字符数
mOneRunNum := numRows*2 - 2
// 总的轮数(向上取整)
mAllRun := int(math.Ceil(float64(mStrLen) / float64(mOneRunNum)))
mSlice := make([]byte, 0, mStrLen)
for i := 0; i < numRows; i++ {
// 当前行首个字符的起始下标
mIdx := i
for j := 0; j <= mAllRun && mIdx < mStrLen; j++ {
mSlice = append(mSlice, s[mIdx])
// 一轮中斜的部分 需要不是首尾行的时候 且 不能越界字符串长度
// mIdx+mOneRunNum-2*i 可以解释为 下一轮当前位的字符向前推导,找到当前轮同行的第二个字符
if i > 0 && i < numRows-1 && mIdx+mOneRunNum-2*i < mStrLen {
mSlice = append(mSlice, s[mIdx+mOneRunNum-2*i])
}
mIdx += mOneRunNum
}
}
return string(mSlice)
}
一点点笔记,以便以后翻阅。



被折叠的 条评论
为什么被折叠?



