Python学习日记016——外观数列

题目来源:LeetCode题库——外观数列
给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
注意:整数序列中的每一项将表示为一个字符串。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:

1
11
21
1211
111221

第一项是数字 1
描述前一项,这个数是 1 即 “一个 1 ”,记作 11
描述前一项,这个数是 11 即 “两个 1 ” ,记作 21
描述前一项,这个数是 21 即 “一个 2 一个 1 ” ,记作 1211
描述前一项,这个数是 1211 即 “一个 1 一个 2 两个 1 ” ,记作 111221
Example1:
输入: 1
输出: “1”
解释:这是一个基本样例。
Example2:
输入: 4
输出: “1211”
解释:当 n = 3 时,序列是 “21”,其中我们有 “2” 和 “1” 两组,“2” 可以读作 “12”,也就是出现频次 = 1 而 值 = 2;类似 “1” 可以读作 “11”。所以答案是 “12” 和 “11” 组合在一起,也就是 “1211”。
链接:https://leetcode-cn.com/problems/count-and-say

外观数列——利用指针移位、计数
通过题目的描述和示例的展示,我们很容易得到一种思路:就是想读数一样从前往后依次遍历。如 “1211” ,我们从第一位看,第二位和第一位不同,则第一位是独立的,表示 1 个 1,在结果中先计入“11” ;第二位和第三位不同,则第二位是独立的,表示 1 个 2,在结果中加入“12”,则为“11 12” ;第三位第四位相同,则它俩是平等的,表示 2 个 1 ,在结果中加入“21”,则为“11 12 21”,即 “111221”就是 “1211” 的下一行外观数列。
按照这样的思路,我们可以设置两个指针,一个用来移位,一个用来计数。移位指针每次向后移动一位,若当前位的值与前一位的值不同:则此次计数过程结束,计数指针代表的值为 1 ,返回 1 个当前移位指针前一位的值(如x),即 “1 x” 。若移位指针当前位的值与前一位的值相同,那么计数指针所代表的值加 1 ,移位指针继续向后移动,直到当前位的值与前一位的值不相等,此时返回计数指针和移位指针前一位代表的值(如计数指针代表 y,移位指针前一位是 z),即 “y z”。
具体实现过程如下:

class Solution:
    def countAndSay(self, n: int) -> str:
        if n == 1:
            return "1"
        else:
            initial_str = '1'
            for i in range(2,n+1):
                moment_str = ''
                count = 1       #计数指针
                for j in range(1,len(initial_str)):      #j是移位指针
                    if initial_str[j] == initial_str[j-1]:
                        count += 1
                    else:
                        moment_str += str(count) + initial_str[j-1]
                        count = 1
                moment_str += str(count) + initial_str[-1]
                initial_str = moment_str
            return moment_str

学习过程中,欢迎指正。