这是在接受采访时向我询问的。
我给了一个字符串,其字符仅来自集合{a,b,c}。查找不包含集合中所有字符的所有子字符串。例如,仅包含a的子字符串,仅包含b,仅包含c或仅包含a,b或仅包含b,c或仅包含c,a。我通过生成所有子串并测试它们给了他天真的O(n ^ 2)解决方案。
面试官想要一个O(n)解决方案。
编辑:我的尝试是使用a,b,c的最后一个索引并从左到右运行一个指针,并且任何时候所有3个都被计算在内,更改子字符串的开头以排除最早的一个并再次开始计数。它似乎并不详尽
因此,例如,如果字符串是abbcabccaa
,
让i
成为遍历字符串的指针。让start
成为子字符串的开头。
1)i = 0,start = 0
2)i = 1,start = 0,last_index(a)= 0 - > 1个子串 - 一个
3)i = 2,start = 0,last_index(a)= 0,last_index(b)= 1 - > 1 substring ab
4)i = 3,start = 0,last_index(a)= 0,last_index(b)= 2 - > 1 substring abb
5)i = 4,start = 1,last_index(b)= 2,last_index(c)= 3 - > 1个子串bbc(从子串中删除了一个)
6)i = 5,start = 3,last_index(c)= 3,last_index(a)= 4 - > 1个子串ca(从子串中删除b)
但这并非详尽无遗
答案 0 :(得分:0)
为了获得比O(n)更好的东西,我们可能需要额外的假设(可能最长的子串具有此属性)。
考虑长度为n的aaaaaaaaaabbbbbbbbbb
形式的字符串。至少有O(n ^ 2)个可能的子串,所以如果我们想要列出它们,我们需要O(n ^ 2)时间。
我想出了最长子串的线性解决方案。
从由S
分隔的所有子字符串中设置a
,将所有子字符串分隔为b
,最后将所有子字符串分隔为c
。每个步骤都可以在O(n)中完成,因此我们有O(3n),因此O(n)。
示例:强>
拿aaabcaaccbaa
。
在这种情况下,设置S
包含:
a
分隔的子字符串:bc
,ccb
b
分隔的子字符串:aaa
,caacc
c
分隔的子字符串:aaab
,aa
,baa
。set 是指在O(1)中添加和查找具有给定键的元素的数据结构。
答案 1 :(得分:0)
鉴于原始定义中的问题无法在O(N ^ 2)时间内解决,正如一些评论指出的那样,我建议用计算子串数的线性算法(它们的价值不一定是唯一的,但在原始字符串中的位置是唯一的。)
算法
示例
S = 'AACB'
使用'a'打破它只给'cb',所以count = 3.对于C ='b',我们有'aac',这使得count = 3 + 6 = 9.使用C ='c'我们得到'aa'和'b',所以count = 9 + 3 + 1 = 13.现在我们要做减法:'aa': - 3,'c': - 1,'b': - 1。所以我们 count = 8 。
8个子串是:
'a'
'a' (the second char this time)
'aa'
'ac'
'aac'
'cb'
'c'
'b'