字符串包含问题算法

来源:互联网 发布:贪心算法汽车加油问题 编辑:程序博客网 时间:2024/05/29 05:55

现在假设有2个字符串r和s,其中m=r.len>n=s.len,设计一个算法判断字符串s中的每个字符在r串中均存在.

 

显然,很容易想到的一个算法,最粗鲁最暴力算法,其时间复杂度O(m*n)(也就是对s字符串中的每个字符在r中进行查找判断)。这或许是我自己想到的最快的方法了。显而易见,这样的算法或许不是算法。如何降低其时间复杂度呢?当时我想到了利用hash算法,但是没有仔细深入思考,然后看了字符串是否包含问题这篇文章,可谓收获颇多。现在将看到的算法重新总结一次,大体可以总结为以下几类:

1、先排序后比较

显然,排序的方法我们有多重选择,其中最常见的位快速排序,这样时间复杂度将会降低到

O(nlogn+mlogm+n).在原文中,提到了计数排序方法(此时我还不确定我是否见过此排序方法,稍候学习下),可以讲时间复杂度降低到O(m+n)

2、利用hash table

首先将s串中的字符hash后,然后再hash r串中的字符,再进行比较。

 1、hash[26],先全部清零,然后扫描短的字符串,若有相应的置1,
 2、计算hash[26]中1的个数,记为m 
 3、扫描长字符串的每个字符a;若原来hash[a] == 1 ,则修改hash[a] =0,并将m减1;若hash[a] == 0,则不做处理 
 4、若m == 0 or 扫描结束,退出循环。

原文中O(n+m)的数组存储方法我觉得其实也就是hash方法而已。

3、最精妙的方法——利用素数乘积

【1】定义最小的26个素数分别与字符'A'到'Z'对应。
【2】遍历长字符串,求得每个字符对应素数的乘积。
【3】遍历短字符串,判断乘积能否被短字符串中的字符对应的素数整除。
【4】输出结果。

上述算法的时间复杂度为O(m+n),时间复杂度最好的情况为O(n)。这个算法思路非常好,可以用到很多方面。

下面这个题目可以使用到这个方法:

一个单词单词字母交换,可得另一个单词,如army->mary,成为兄弟单词。提供一个单词,在字典中找到它的兄弟。描述数据结构和查询过程。

谢谢参考文献作者所做总结。

0 0
原创粉丝点击