力扣刷题[6] Go代码实现

代码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)
}

一点点笔记,以便以后翻阅。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小印丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值