返回

1408. 数组中的字符串匹配 : 解题指南,快速掌握模拟思想

后端

探索 LeetCode 第 1408 号问题:“数组中的字符串匹配”

欢迎来到我们的技术探索之旅,今天,我们将深入研究 LeetCode 上的第 1408 号问题:“数组中的字符串匹配”。这道题不仅能检验你的模拟算法技能,还能让你对字符串处理有更透彻的理解。准备好迎接挑战了吗?让我们开始吧!

问题概述

题意:
给你一个字符串 s 和一个字符数组 words,你需要计算 s 中有多少个子字符串与 words 中的字符串完全匹配。

注意点:

  • 子字符串是可以连续或不连续的。

示例:

Example 1:

输入:s = "leetcode", words = ["leet", "code"]
输出:2
解释:有 2 个子字符串在 "leetcode" 中匹配 "words",它们分别是 "leet""code"

解决方案

解决这道题,我们可以采用以下三种方法:

暴力模拟

  • 步骤:

    1. 枚举出字符串 s 的所有子字符串。
    2. 检查每个子字符串是否与 words 中的字符串完全匹配。
    3. 统计匹配的子字符串数量。
  • 优点:

    • 简单易懂。
    • 适用于数据规模较小的情况。
  • 缺点:

    • 时间复杂度较高,为 O(n^3)。
    • 空间复杂度较高,需要存储所有子字符串。

双指针

  • 步骤:

    1. 使用两个指针 ij 表示子字符串的左右边界。
    2. 移动指针 j 向右,直到 s[i:j]words 中的字符串完全匹配。
    3. 移动指针 i 向右一位,并将指针 j 重新指向 i
    4. 重复步骤 2-3,直到指针 j 到达字符串 s 的末尾。
  • 优点:

    • 时间复杂度为 O(n^2)。
    • 空间复杂度为 O(1)。
  • 缺点:

    • 对于数据规模较大的情况,仍然可能会比较耗时。

前缀和

  • 步骤:

    1. 预处理出每个子字符串的哈希值。
    2. 使用哈希表存储每个子字符串的哈希值。
    3. 对于每个单词 word,检查它的哈希值是否在哈希表中。
  • 优点:

    • 时间复杂度为 O(n)。
    • 空间复杂度为 O(n)。
  • 缺点:

    • 需要预处理每个子字符串的哈希值。

代码示例

# 暴力模拟
def stringMatching(s, words):
    count = 0
    for i in range(len(s)):
        for j in range(i + 1, len(s) + 1):
            substring = s[i:j]
            if substring in words:
                count += 1
    return count

# 双指针
def stringMatching(s, words):
    count = 0
    i = 0
    j = 0
    while j <= len(s):
        substring = s[i:j]
        if substring in words:
            count += 1
        if j == len(s):
            i += 1
            j = i
        else:
            j += 1
    return count

# 前缀和
def stringMatching(s, words):
    hash_map = {}
    for i in range(len(s)):
        for j in range(i + 1, len(s) + 1):
            substring = s[i:j]
            hash_map[substring] = hash(substring)

    count = 0
    for word in words:
        if word in hash_map:
            count += 1

    return count

总结

通过本文的学习,我们深入探究了 LeetCode 第 1408 号问题:“数组中的字符串匹配”。我们从题目的概述入手,逐步剖析题意,并介绍了三种不同的解决思路:暴力模拟、双指针和前缀和。希望通过这些讲解,你能对模拟算法有更深刻的理解,并在编程实践中游刃有余。

常见问题解答

  • Q1:如何判断一个子字符串与单词完全匹配?
    A1:两个字符串中每个字符都完全相同。

  • Q2:为什么暴力模拟的时间复杂度较高?
    A2:因为暴力模拟需要枚举出所有的子字符串,而子字符串的数量与字符串的长度成二次方关系。

  • Q3:双指针法中,为什么指针 i 要向右移动一位?
    A3:因为双指针法检查的是连续的子字符串,移动指针 i 向右一位可以避免重复检查。

  • Q4:前缀和法中,为什么需要预处理每个子字符串的哈希值?
    A4:因为哈希值可以快速判断两个字符串是否相等,从而减少了比较的时间。

  • Q5:这三种方法中,哪种方法最优?
    A5:取决于数据规模和字符串长度。对于数据规模较小或字符串长度较短的情况,暴力模拟和双指针法都是不错的选择。对于数据规模较大或字符串长度较长的的情况,前缀和法更具优势。