144-38. 外观数列

给定一个正整数 n ,输出外观数列的第 n 项。(前两个我写的,后面一个你猜,反正比我的好)

class Solution(object):
    def countAndSay1(self, n):
        """
        :type n: int
        :rtype: str
        """
        if n == 1:
            return str(n)

        if n == 2:
            return str(11)

        temp_str = ""
        i = 1

        while i <= n - 2:
            temp_list = []
            # 由于下面的while循环中使用的是j+1所以给后面随意补一个字符(这个字符永远取不到,所以不用担心)
            temp_str = "{}".format(i) if not temp_str else temp_str + "*"

            if len(temp_str) < 2:
                temp_str = "1{}".format(temp_str)

            j = 0
            k = 1
            while j + 1 < len(temp_str):
                while j + 1 < len(temp_str) and temp_str[j] == temp_str[j+1]:
                    k += 1
                    j += 1

                temp_list.append((temp_str[j], k))

                k = 1
                j += 1

            temp_str = ""
            for key, value in temp_list:
                temp_str += (str(value) + key)

            i += 1

        return temp_str

    def countAndSay2(self, n):
        """稍微做了一些优化
        :type n: int
        :rtype: str
        """
        if n == 1:
            return str(n)

        if n == 2:
            return str(11)

        temp_str = ""
        i = 1

        while i <= n - 2:
            # 由于下面的while循环中使用的是j+1所以给后面随意补一个字符(这个字符永远取不到,所以不用担心)
            temp_str = "{}".format(i) if not temp_str else temp_str + "*"

            # 这里当当temp_str长度小于2的时候你需要给补齐,否则下面j + 1必定报错
            if len(temp_str) < 2:
                temp_str = "1{}".format(temp_str)

            j = 0
            k = 1
            temp_str2 = ""
            while j + 1 < len(temp_str):
                while j + 1 < len(temp_str) and temp_str[j] == temp_str[j+1]:
                    k += 1
                    j += 1

                temp_str2 += (str(k) + temp_str[j])

                k = 1
                j += 1

            temp_str = temp_str2
            i += 1

        return temp_str

    def countAndSay3(self, n):
        """这个双指针挺好的
        :type n: int
        :rtype: str
        """
        pre = ''
        cur = '1'

        # 从第 2 项开始
        for _ in range(1, n):
            # 这里注意要将 cur 赋值给 pre
            # 因为当前项,就是下一项的前一项。有点绕,尝试理解下
            pre = cur
            # 这里 cur 初始化为空,重新拼接
            cur = ''
            # 定义双指针 start,end
            start = 0
            end = 0
            # 开始遍历前一项,开始描述
            while end < len(pre):
                # 统计重复元素的次数,出现不同元素时,停止
                # 记录出现的次数,
                while end < len(pre) and pre[start] == pre[end]:
                    end += 1
                # 元素出现次数与元素进行拼接
                cur += str(end - start) + pre[start]
                # 这里更新 start,开始记录下一个元素
                start = end

        return cur


if __name__ == '__main__':
    s = Solution()
    n = 30

    print(s.countAndSay(n))
原文地址:https://www.cnblogs.com/liuzhanghao/p/14288413.html