AcWing 137雪花雪花雪花,Python逆序循环,Python List删除元素,Python re模块解析,Python KMP算法实现字符串匹配
剑指刷题:2019/5/27
AcWing 137雪花雪花雪花
【转】https://blog.csdn.net/qq_30277239/article/details/90273218
字符串的最小表示法:
求一个字符串的循环同构体中最小字典序的那个。比如bcda的循环同构体有bcda,cdab,dabc,abcd,其中最小表示法是abcd。
暴力求解O(n$^2$):
定义双指针i = 0,j = 1,首先a < b所以字符串的第二个位置不会作为最优解字符串的开头,同理,后面的cd也都不会作为字符串的开头,直到j = 4匹配到了另一个a,于是i,j均右移,发现后面的bc也都相等,继续右移,直至遇见了d < e,所以abce不可能是最小表示法的前缀,然后j又回到下标为5的位置,i也回到开头,a < b,继续比较。
优化:
j指针不再跳回原位置进行下一次匹配,直接从字典序大的那个开始
例如:
abcdabcebdd
adcebddabcd
两个循环同构体在d和e的位置失配时,第一个指针重新回到下标为0的位置,而第二个指针不需要在从下标为0的位置的后一个位置再进行比较,既然abce都失去了前缀的资格,那么第二个指针从第五个字符b再次开始比较即可
1 | # -*- coding: utf-8 -*- |
本题需要判断雪花是否相同,只要两片雪花的六个角的最小表示法相同,我们就可以断定这两片雪花完全相同,所不同的是:上面介绍的最小表示法只能自左往右循环,而本题可以自右向左循环,只需读入时备份一下逆置的数组,然后仅保留两个数组的最小表示即可。
本题的主要思路就是,先对所有雪花都哈希映射到某个值,只有两片雪花散列后的值相等时他们才可能相等,再比较他们的最小表示法即可验证。
Python逆序循环
1 | #逆序循环 |
Python List删除元素
1.使用del删除元素
根据索引删除,删除索引范围内的元素,删除整个列表,del操作没有返回值
1 | l = [1,2,3,4] |
2.使用list方法pop删除元素
根据索引删除,返回索引位置的元素
1 | l = [1,2,3,4] |
3.使用切片删除元素
1 | l = [1,2,3,4] |
4.使用list方法remove删除指定值的元素
删除第一个符合条件的元素
1 | l = [1,2,3,4] |
Python re模块解析
提前编译正则表达式
http://www.codebelief.com/article/2017/01/python-standard-library-re-module-functions/
1 | import re |
仅匹配第一个满足条件的字符串
1 | re.search(pattern, string, flags=0) |
仅匹配字符串的起始位置子串
1 | re.match(pattern, string, flags=0) |
通过匹配表达式来切割字符串
如果指定了 maxsplit
的值,且不为0,那么最多进行 maxsplit
次的字符串切割操作。最后剩下的未被切割的字符串,将作为一个整体添加到结果列表中。这种情况下,结果列表最多会有 maxsplit
+ 1 项。
1 | re.split(pattern, string, maxsplit=0, flags=0) |
以列表的形式返回所有不重叠的匹配结果,空匹配结果同样会被添加到列表中。
如果表达式中含有捕获分组,那么表达式匹配到的结果中,只有捕获分组里的内容会被添加到结果列表中
1 | re.findall(r'(\w)\d', 'a1 b2 c3 d4') |
返回一个迭代器,包含所有不重叠的匹配结果,空匹配结果同样会被添加到列表中。
1 | f = re.finditer(pattern, string, flags=0) |
返回一个被替换后的字符串
1 | re.sub(pattern, repl, string, count=0, flags=0) |
Python KMP算法实现字符串匹配
KMP算法:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
部分匹配值表:前缀和后缀的最长的共有元素长度
移动位数 = 已匹配的字符数 - 对应的部分匹配值
nexts数组即为部分匹配值表
1 | """ |