给定一个正整数 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))