459.重复的子字符串
- 根据题意,有这样的一个子字符串存在,那么子字符串乘以重复的次数应该等于原字符串。
- trick:遍历的时候 都不用遍历结束,只需要遍历到中间位置,因为子串结束位置大于中间位置的话,一定不能重复组成字符串。
class Solution(object):
def repeatedSubstringPattern(self, s):
"""
:type s: str
:rtype: bool
"""
temp = ''
for i in range(len(s) // 2):
temp += s[i]
if temp * (len(s) // len(temp)) == s:
return True
return False
class Solution(object):
def repeatedSubstringPattern(self, s):
"""
:type s: str
:rtype: bool
"""
for i in range(len(s) // 2):
temp = s[: (i + 1)]
if temp * (len(s) // len(temp)) == s:
return True
return False
- 移动匹配:
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
temp = s + s
temp = temp[1 : (len(temp) - 1)]
return s in temp
复杂度分析:
- 第一种写法的时间复杂度应该是 O(n) 因为 temp += s[i], s[i]数组索引是O(1)
- 第二种写法的时间复杂度应该是 O(n*m); 因为数组切片是 O(m).
- 小结:基本是同样的解法,但是采用的方式不同造成时间复杂度的不同!
- 移动匹配法:
- 字符串长度为n,两个字符串s相加的时间复杂度为O(n),字符串的切片操作时间复杂度也为O(m),最后一步,查找一个字符串是否在另一个字符串中出现,这个暴力解法的时间复杂度是O(n*m), 库函数实现中的时间复杂度一般为O(m+n),所以全部加起来的复杂度仍为O(n)。
- time complexity of python's if substring in string:
- The time complexity is O(N) on average, O(NM) worst case (N being the length of the longer string, M, the shorter string you search for). As of Python 3.10, heuristics are used to lower the worst-case scenario to O(N + M) by switching algorithms
- https://stackoverflow.com/questions/35220418/runtime-of-pythons-if-substring-in-string#:~:text=The%20time%20complexity%20is%20O,%2B%20M)%20by%20switching%20algorithms.
总结:
先定义一个空字符串,然后利用 += 对字符串拼接;还有一种方法是利用数组,也就是先将字符串转换成数组,然后利用数组的.append()方法加入,最后 ' '.join()转换回字符串。
那么这两种方法有什么区别?
- Python中字符串是不可变对象,修改字符串就得将原字符串中的值复制,开辟一块新的内存,加上修改的内容后写入到新内存中,以达到“修改”字符串的效果。在使用“+”拼接字符串时,正是使用了重复性的复制、申请新内存、写入值到新内存的工作一遍遍的将字符串的值修改。
而使用join()方法拼接字符串时,会先计算总共需要申请多少内存,然后一次性申请所需内存并将字符串复制过去。这样便省去了重复性的内存申请和写入,节省了时间消耗。