掘金28:剖析strStr()函数,迈向高效字符串搜索之路
2023-12-22 17:17:58
字符串搜索算法:从蛮力法到高效的KMP算法
算法入门:蛮力法
踏入字符串搜索的领域,我们首先邂逅的是朴素而直观的蛮力法。它就像一个勤奋的工人,逐个字符比较,孜孜不倦地寻找目标字符串在待搜索字符串中的踪影。虽然简单易懂,但蛮力法却因其时间复杂度O(mn)而备受诟病,其中m为目标字符串的长度,n为待搜索字符串的长度。
迈向高效:KMP算法
为了提升字符串搜索的效率,计算机科学家们呕心沥血,提出了巧妙的KMP算法。它巧妙地利用失效函数,记录目标字符串中每个字符之前最长的匹配前缀长度,从而大幅减少不必要的比较。KMP算法的时间复杂度仅为O(m+n),大幅降低了搜索成本,堪称字符串搜索领域的里程碑。
算法对比与权衡
蛮力法和KMP算法各有千秋,在不同场景下表现出不同的优势。当待搜索字符串较短时,蛮力法凭借其无需构建失效函数的优势,可能更加高效。然而,当待搜索字符串变长时,KMP算法的优势则愈发明显。
代码实现与示例
为了加深理解,让我们用Python语言实现这两种算法:
蛮力法
def strStr_brute_force(haystack, needle):
for i in range(len(haystack) - len(needle) + 1):
if haystack[i:i+len(needle)] == needle:
return i
return -1
KMP算法
def strStr_KMP(haystack, needle):
failure = build_failure_function(needle)
i = 0
j = 0
while i < len(haystack):
if haystack[i] == needle[j]:
i += 1
j += 1
if j == len(needle):
return i - j
if j > 0:
j = failure[j-1]
else:
i += 1
return -1
def build_failure_function(needle):
failure = [0] * len(needle)
j = 0
for i in range(1, len(needle)):
while j > 0 and needle[i] != needle[j]:
j = failure[j-1]
if needle[i] == needle[j]:
j += 1
failure[i] = j
return failure
结语
通过蛮力法和KMP算法,我们踏上了字符串搜索之旅的第一步。虽然蛮力法简单直观,但KMP算法在效率上独占鳌头。在LeetCode刷题的道路上,理解并掌握这些算法将为我们扫清障碍,勇攀高峰。让我们继续探索字符串处理的奥秘,在算法的王国里大展身手!
常见问题解答
1. 什么是失效函数?
失效函数记录了目标字符串中每个字符之前最长的匹配前缀长度,用于指导KMP算法跳过不必要的比较。
2. 为什么KMP算法比蛮力法更有效率?
KMP算法利用失效函数减少不必要的比较,从而大幅降低时间复杂度。
3. 蛮力法和KMP算法哪个更适合短字符串?
当待搜索字符串较短时,蛮力法可能更胜一筹,因为无需构建失效函数。
4. KMP算法是如何构建失效函数的?
KMP算法逐个字符构建失效函数,记录目标字符串中每个字符之前最长的匹配前缀长度。
5. 除了蛮力法和KMP算法,还有哪些字符串搜索算法?
还有许多其他字符串搜索算法,如Boyer-Moore算法、Rabin-Karp算法和有限自动机。