字符串包含

不等长的字符串包含问题(多对一)

A字符串>B字符串,问A字符是否包含字符串B的所有字符。是否包含子串问题同样适合。

1ABCDEFGHLMNOPQRS"是否包含"ODCGSRQPOMC"

解法一:

(1)先让字符串有序。时间复杂度为o(nlogn);

(2)比较两个有序的字符串。时间复杂度为O(m+n);

 

比较两个有序字符串的通用算法

用两层循环,外层循环是短的字符串,内层循环是长的字符串。

for(int i=0,j=0;i<t.length;i++){

//外层短字符串,

while(j<s.length&&t[i]>s[j]){

//内层长字符串,每次都是从当前j继续遍历,所以内层循环总共只循环了一轮。所以总共循环次数On*1+O(m)

j++;

}

if (j>=s.length||t[i]<s[j]) {//这一步是提前停止循环

//j>=s.length表示只能找到全比t[i]小的s[j]例如s:ADEFG  tAHI

//s[j]>t[i]表示只能找到比t[i]大的s[j],因为是升序,所以找到一个这样的s[j],后面的都比t[i]大。例如s:ADEFG   t:ABC

return false;

}

 

 

 

解法二:

使用散列表的思想。

(1)设散列表为装有26个素数的数组。

(2)将长字符串与散列表建立对应关系(通过p[s[i]-'A']),生成乘积

(3)短字符串与散列表建立关系,看短字符串是否是乘积的因子

空间复杂度26,时间复杂度Om+n

 

解法三:

使用散列表思想,这里的散列表利用位运算,可以将空间复杂度降低到O1

补充:位运算

 

(a)&相同位的两个数字都为1,则为1若有一个不为1,则为0

00101

11100

---------

00100

(b)|相同位的两个数字都为0,则为0若有一个不为0,则为1

00101

11100

  ----------------

    11101

(1)利用位运算(或|生成散列表,hash|=1<<s[i]-'A';

(2)利用位运算(与&)判断短字符串是否被包含在长字符hash&1<<t[j]-'A'

兄弟字符串包含问题

兄弟字符串即等长的字符串,相当于字符串包含问题的特殊情况。也可以用散列表。

1GCDMOPQSR""DCGSRQPOM是否是兄弟字符串?

(1)生成长度为26的数组当做散列表。

(2)将字符串M与散列表建立对应关系hash[s[i]-'A']。并将每个字符出现的字符放入散列表中hash[s[i]-'A']++。

(3)将字符串N与散列表建立对应关系hash[t[j]-'A'],并将每个字符出现的字符放入散列表中hash[t[j]-'A']--

你可能感兴趣的:(字符串包含)