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:

总结:

先定义一个空字符串,然后利用 += 对字符串拼接;还有一种方法是利用数组,也就是先将字符串转换成数组,然后利用数组的.append()方法加入,最后 ' '.join()转换回字符串。

那么这两种方法有什么区别

  • Python中字符串是不可变对象,修改字符串就得将原字符串中的值复制,开辟一块新的内存,加上修改的内容后写入到新内存中,以达到“修改”字符串的效果。在使用“+”拼接字符串时,正是使用了重复性的复制、申请新内存、写入值到新内存的工作一遍遍的将字符串的值修改。
    而使用join()方法拼接字符串时,会先计算总共需要申请多少内存,然后一次性申请所需内存并将字符串复制过去。这样便省去了重复性的内存申请和写入,节省了时间消耗。