字符串及其反转中是否存在同一子字符串:深入解析与解决方案
在字符串处理和算法设计中,查找特定模式的子字符串是一项常见且重要的任务。今天,我们将探讨一个有趣的问题:判断一个字符串中是否存在一个长度为2的子字符串,在其反转后的字符串中也出现。这个问题不仅考验了我们的字符串操作能力,还涉及了高效算法的设计。
问题描述
题目编号:3083
标题:字符串及其反转中是否存在同一子字符串
难度:简单
相关标签:字符串,哈希表
相关企业:未指定
题目
给你一个字符串 s
,请你判断字符串 s
是否存在一个长度为 2 的子字符串,在其反转后的字符串中也出现。
如果存在这样的子字符串,返回 true
;如果不存在,返回 false
。
示例 1:
输入:s = "leetcode"
输出:true
解释:子字符串 "ee" 的长度为 2,它也出现在 reverse(s) == "edocteel" 中。
示例 2:
输入:s = "abcba"
输出:true
解释:所有长度为 2 的子字符串 "ab"、"bc"、"cb"、"ba" 也都出现在 reverse(s) == "abcba" 中。
示例 3:
输入:s = "abcd"
输出:false
解释:字符串 s 中不存在满足「在其反转后的字符串中也出现」且长度为 2 的子字符串。
提示:
1 <= s.length <= 100
- 字符串
s
仅由小写英文字母组成。
解题思路
为了判断字符串 s
中是否存在一个长度为2的子字符串,其反转后的字符串也在 s
中出现,我们可以采取以下步骤:
-
遍历字符串
s
:对于每一个可能的长度为2的子字符串,提取并进行反转。 -
检查反转后的子字符串是否存在于原字符串
s
中。 -
优化:为了提高效率,可以使用哈希表(如集合)存储所有长度为2的子字符串,以便快速查找。
不过,由于字符串长度限制在100以内,直接遍历和检查的时间复杂度也是可以接受的。因此,以下提供了一个简单且有效的解决方案。
代码实现
class Solution:
def isSubstringPresent(self, s: str) -> bool:
n = len(s)
for i in range(n - 1):
# 提取长度为2的子字符串
a = s[i:i+2]
# 反转子字符串并检查是否存在于原字符串中
if a[::-1] in s:
return True
return False
代码解析
让我们逐步解析上述代码的工作原理:
-
获取字符串长度:
n = len(s)
这一步是为了确定遍历的范围,避免索引越界。
-
遍历字符串,提取子字符串:
for i in range(n - 1): a = s[i:i+2]
由于我们需要提取长度为2的子字符串,因此遍历范围是从
0
到n-2
。 -
反转子字符串并检查存在性:
if a[::-1] in s: return True
a[::-1]
用于反转子字符串。如果反转后的子字符串在原字符串s
中存在,则立即返回True
。 -
如果遍历结束后未找到符合条件的子字符串,返回
False
:return False
示例解析
示例 1:
- 输入:
s = "leetcode"
- 提取的子字符串及其反转:
- “le” -> “el” (不在
s
中) - “ee” -> “ee” (在
s
中)
- “le” -> “el” (不在
- 由于子字符串 “ee” 的反转 “ee” 存在于
s
中,返回True
。
示例 2:
- 输入:
s = "abcba"
- 提取的子字符串及其反转:
- “ab” -> “ba” (在
s
中) - “bc” -> “cb” (在
s
中) - “cb” -> “bc” (在
s
中) - “ba” -> “ab” (在
s
中)
- “ab” -> “ba” (在
- 多个子字符串满足条件,返回
True
。
示例 3:
- 输入:
s = "abcd"
- 提取的子字符串及其反转:
- “ab” -> “ba” (不在
s
中) - “bc” -> “cb” (不在
s
中) - “cd” -> “dc” (不在
s
中)
- “ab” -> “ba” (不在
- 无子字符串满足条件,返回
False
。
时间复杂度分析
-
时间复杂度:O(n^2)
在最坏情况下,对于每个长度为2的子字符串,我们需要检查它的反转是否存在于字符串
s
中。字符串的in
操作在平均情况下是O(n),因此整体时间复杂度为O(n^2)。 -
空间复杂度:O(1)
只使用了常数级别的额外空间。
由于题目中字符串的最大长度为100,时间复杂度在这个范围内是可以接受的。
优化思路
尽管当前的解决方案已经足够高效,但我们仍可以尝试优化时间复杂度:
-
使用哈希表存储所有长度为2的子字符串:
- 预先遍历一次字符串,存储所有长度为2的子字符串到一个集合中。
- 然后再遍历一次,检查每个子字符串的反转是否在集合中。
-
时间复杂度优化:
- 通过使用集合,查找操作可以从O(n)优化到O(1),从而将整体时间复杂度降为O(n)。
优化后的代码
class Solution:
def isSubstringPresent(self, s: str) -> bool:
n = len(s)
substr_set = set()
# 存储所有长度为2的子字符串
for i in range(n - 1):
substr_set.add(s[i:i+2])
# 检查反转后的子字符串是否存在
for substr in substr_set:
reversed_substr = substr[::-1]
if reversed_substr in substr_set:
return True
return False
优化后的时间复杂度
-
时间复杂度:O(n)
两次遍历字符串,每次都是O(n),因此总时间复杂度为O(n)。
-
空间复杂度:O(n)
需要存储所有长度为2的子字符串,最多有O(n)个。
结论
通过本文的解析,我们了解了如何判断一个字符串中是否存在一个长度为2的子字符串,其反转后的字符串也在原字符串中出现。初始的双重遍历方法虽然简单,但通过使用哈希表的优化,我们成功将时间复杂度从O(n^2)降至O(n),提高了算法的效率。
这种问题在实际应用中具有广泛的意义,例如在生物信息学中的基因序列分析,或是在文本处理中的模式匹配等领域。掌握高效的字符串处理技巧,将为解决更复杂的问题奠定坚实的基础。
如果您对本篇文章有任何疑问或建议,欢迎在评论区留言讨论!