1967-作为子字符串出现在单词中的字符串数目
给你一个字符串数组 patterns
和一个字符串 word
,统计 patterns
中有多少个字符串是 word
的子字符串。返回字符串数目。
子字符串 是字符串中的一个连续字符序列。
示例 1:
**输入:** patterns = ["a","abc","bc","d"], word = "abc"
**输出:** 3
**解释:**
- "a" 是 " _ **a**_ bc" 的子字符串。
- "abc" 是 " _ **abc**_ " 的子字符串。
- "bc" 是 "a _ **bc**_ " 的子字符串。
- "d" 不是 "abc" 的子字符串。
patterns 中有 3 个字符串作为子字符串出现在 word 中。
示例 2:
**输入:** patterns = ["a","b","c"], word = "aaaaabbbbb"
**输出:** 2
**解释:**
- "a" 是 "a _ **a**_ aaabbbbb" 的子字符串。
- "b" 是 "aaaaabbbb _ **b**_ " 的子字符串。
- "c" 不是 "aaaaabbbbb" 的字符串。
patterns 中有 2 个字符串作为子字符串出现在 word 中。
示例 3:
**输入:** patterns = ["a","a","a"], word = "ab"
**输出:** 3
**解释:** patterns 中的每个字符串都作为子字符串出现在 word " _ **a**_ b" 中。
提示:
1 <= patterns.length <= 100
1 <= patterns[i].length <= 100
1 <= word.length <= 100
patterns[i]
和word
由小写英文字母组成
方法一:暴力匹配
思路与算法
我们可以让字符串数组 patterns 中的每个字符串 pattern 都与 word 匹配一次,同时统计其中为 word 子串的字符串数目。
我们用函数 check}(\textit{pattern}, \textit{word}) 来判断字符串 pattern 是否是 word 的子串。我们假设 pattern 的长度为 m。在该函数中,我们让 pattern 与 word 的每个长度为 m 的子串均匹配一次。
为了减少不必要的匹配,我们每次匹配失败即立刻停止当前子串的匹配,对下一个子串继续匹配。如果当前子串匹配成功,我们返回 true;如果所有子串都匹配失败,则返回 false。
代码
1 | class Solution { |
1 | class Solution: |
复杂度分析
时间复杂度:O(n \times \sum_i m_i),其中 n 为字符串 word 的长度,m_i 为字符串 patterns}[i] 的长度。
对于 patterns 中的每个字符串 patterns}[i],暴力匹配判断是否为 word 子串的时间复杂度为 O(n \times m_i)。
空间复杂度:O(1)。
方法二:KMP 算法
思路与算法
在方法一中,每一次调用函数 check}(\textit{pattern}, \textit{word}) 进行判断都需要暴力比较 pattern 与 word 中所有长度为 m 的子串,假设 word 的长度为 n,则匹配的时间复杂度为 O(nm)。
我们可以对函数 check}(\textit{pattern}, \textit{word}) 中暴力比较的过程进行优化。在这里,我们使用 KMP 算法对匹配过程进行优化。如果读者不熟悉 KMP 算法,可以阅读「28. 实现 strStr() 的官方题解」 中的方法二。
代码
1 | class Solution { |
1 | class Solution: |
复杂度分析
时间复杂度:O(nk + \sum_i m_i),其中 n 为字符串 word 的长度,k 为数组 patterns 中的元素数目,m_i 为字符串 patterns}[i] 的长度。
对于 patterns 中的每个字符串 patterns}[i],利用 KMP 算法判断是否为 word 子串的时间复杂度为 O(n + m_i)。
空间复杂度:O(\max_i(m_i)),其中 m_i 为字符串 patterns}[i] 的长度。即为所有 patterns}[i] 的前缀数组的空间开销。