zoukankan      html  css  js  c++  java
  • 报数的golang实现

    报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

    1.     1
    2.     11
    3.     21
    4.     1211
    5.     111221
    • 1 被读作 "one 1" ("一个一") , 即 11。
    • 11 被读作 "two 1s" ("两个一"), 即 21。
    • 21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。

    给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

    注意:整数顺序将表示为一个字符串。

    输入: 1
    输出: "1"
    输入: 4
    输出: "1211"
    理解题意:

    首先我们还是列举一下每个数的输出吧

    第几次输出
    1 1
    2 11
    3 21
    4 1211
    5 111221
    6 312211
    7 13112221
    8 1113213211
    9 31131211131221

    从上面我们可以看出来,对一个数说出来有两种情况:

    • 多个相邻一样:n个几
    • 相邻不一样:1个几
    那函数中重要的思想就是:
    1. 遍历上一次的输出
    2. 然后比较相邻的数
    3. 如果是一样的话,那就在找下一位
    4. 如果是不一样的话,那就要添加到数组中
    核心代码:
    func say(bs []byte) []byte {
        result := make([]byte, 0)
        x, y := 0, 1
        for x < len(bs) { //取出字节数组中的每一个
            //判断相邻位置的是否是一样
            //当是一样的话,那就继续,找到有多少个是一样的
            //当不是一样的话,那就是一个几
            //这里要保证y不能超过bs的长度,不然会panic
            for y < len(bs) && bs[x] == bs[y] {
                y++
            }
            //第二个参数是指有多少个一样的
            // (这里需要注意一点,一定要加上'0',不然字节不对,'0'代表的字节是48,
            // 如果不加上'0',byte(y-x)就是byte(1),这是不对的)
            //第三个参数是指说出来的那个数
            result = append(result, byte(y-x+'0'), bs[x])
    
            //跳过相同的数
            x = y
        }
        return result
    }

    当然我们肯定要一开始就设定第一次的输出为'1'

    func countAndSay(n int) string {
        if n == 1 {
            return "1"
        }
        bs := []byte{'1'}
        for i := 2; i <= n; i++ {
            bs = say(bs)
        }
        return string(bs)
    }

    为什么要用字节数组呢?因为转字符串简单呀!!!

  • 相关阅读:
    asp.net mvc简单分页实例
    aspnetpager使用介绍
    sql server 横向转丛向及FOR XML PATH使用
    js apply使用
    js call使用
    C# JavaScriptSerializer 序列化集合
    【BZOJ4103】[Thu Summer Camp 2015]异或运算 可持久化Trie树
    【BZOJ4177】Mike的农场 最小割
    【BZOJ4205】卡牌配对 最大流
    【BZOJ4358】permu kd-tree
  • 原文地址:https://www.cnblogs.com/TimLiuDream/p/10003802.html
Copyright © 2011-2022 走看看