Count and Say
Question
The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, ...
1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n, generate the sequence.
Answer
solution:
class Solution(object):
def countAndSay(self, n):
"""
:type n: int
:rtype: str
"""
s = '1'
for _ in xrange(n - 1):
s = re.sub(r'(.)\1*', lambda m: str(len(m.group(0))) + m.group(1), s)
return sKnowledge:
这道题目一开始就没理解到题意,后来才知道,是生成一种特定的序列,输入n,则返回该序列第n个的值。发现涉及到lambda和re的问题,趁此总结下。
这种产生固定序列类的题,预设初始值s,然后根据修改再返回新s。
lambda函数,lambda和普通函数相比,就是省去了函数名称而已,此外在使用Python写脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。lambda后是输入项,冒号后是输出值。
lambda更多的是与其他函数进行配合使用,可以节约该函数的参数,比如此题的re.sub以及如下的特殊函数(这些函数都是对于列表的元素进行操作,即每个元素当作lambda x)。
正则表达式的使用
re.sub有三个必选参数:pattern(正则表达式), repl(replace替换值), string(原字符串),返回替换后的字符串,此外还允许使用函数对匹配项进行替换,比如lambda,把找到的匹配项当作m输入:
re.sub(pattern, repl, string)。注意re.sub是找到一个替换一下,找到一个替换一下,所以这里会重复调用正则表达式。正则表达式匹配到的对象(即利用re.findall等查找找到的对象)利用group处理分组。通过用小括号来(字符‘(’和‘)’)包围正则表达式的特定部分,我们可以对内容进行分组然后对这些子组做单独处理。它们可以通过其在正则表达式中从左到右出现的数字顺序来定位(从1开始):match.group(1)。第0个组被预留来存放所有匹配对象:match.group(0)。注意整体的字符串匹配到的内容(group(0))与其中()匹配到的内容(group(1))的区别,要明白!
特殊字符点号".",用以匹配除换行符\n之外的任何单字符。
正则表达式小括号"()",用以提取匹配的字符串。注意不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "\" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推。例子:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹配结果是:成功;匹配到的内容是 "ccccc"。再次匹配下一个时,将得到 999999999。注意:若是利用反向引用的,那么跳开重复的再去匹配,比如例子中的第二个c就不管了,直接到9,类似这里的re.sub的原理
限定符:"*",用以匹配前面的子表达式零次或多次。"+",用以匹配前面的子表达式一次或多次。因为如果这里使用(.)\1_的话,那么在n=2时,由于只有1,找不到另外一个1,那么就会返回nonetype报错。
Reference
Last updated
Was this helpful?