字符串部分算法题(代码随想录)

字符串

1.反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

双指针 直接秒

def reverseString(self, s: List[str]) -> None:
    if s is None :
        return
    n = len(s)
    l,r = 0,n - 1
    while l < r:
        temp = s[l]
        s[l] = s[r]
        s[r] = temp
        l += 1
        r -= 1

2.反转字符串 II

def reverseStr(self, s: str, k: int) -> str:
    n = len(s)
    cnt = (n // (2 * k)) + 1
    re = list(s)
    for i in range(cnt):
        #l,r = -1,-1
        #if i*2*k+k <= n:
        #    l = i*2*k
        #    r = i*2*k+k-1
        #else:
        #    l = i * 2 * k
        #    r = n - 1
        l, r = i * 2 * k, min(i * 2 * k + k - 1, n - 1)
        while l < r:
            re[l],re[r] = re[r],re[l]
            l += 1
            r -= 1
    return ''.join(re)

3.替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

不使用额外的辅助空间

def replaceSpace(self, s: str) -> str:
    cnt = s.count(" ")
    res = list(s)
    res.extend([' ']*cnt*2)
    l,r = len(s) - 1,len(res) - 1
    while l >= 0:
        if s[l] == " ":
            res[r-2:r+1] = "%20"
            r -= 3
        else:
            res[r] = res[l]
            r -= 1
        l -= 1
    return "".join(res)

4.反转字符串中的单词(2)

最直接的思路
def reverseWords(self, s: str) -> str:
    return ' '.join(s.strip().split()[::-1])
不使用额外的空间

去除多余空格

翻转整个字符串

将每个单词翻转

def reverseWords(self, s: str) -> str:
    def reverse(temp,l,r):
        while l < r:
            temp[l], temp[r] = temp[r], temp[l]
            l += 1
            r -= 1
    n = len(s)
    l,r = 0,n - 1
    temp = []
    while l <= r and s[l] == ' ':
        l += 1
    while l <= r and s[r] == ' ':
        r -= 1
    while l <= r:
        if s[l] != ' ':
            temp.append(s[l])
        elif temp[-1] != ' ':
            temp.append(s[l])
        l += 1
    # 翻转字符串
    l,r = 0,len(temp) - 1
    reverse(temp,l,r)
    # 翻转每个单词
    l,r = 0,0
    n = len(temp)
    while l < n:
        while r < n and temp[r] != ' ':
            r += 1
        reverse(temp,l,r - 1)
        r += 1
        l = r
    return ''.join(temp)

5.左旋转字符串

使用切片
不使用切片
def reverseLeftWords(self, s: str, n: int) -> str:
    s = list(s)
    s[:n] = list(reversed(s[:n]))
    s[n:] = list(reversed(s[n:]))
    s.reverse()
    return ''.join(s)

6.实现 strStr()(2)

KMP

举例: a a b a a f

前缀表next 0 1 0 1 2 0

前缀表之和模式串有关

def strStr(self, haystack: str, needle: str) -> int:
    # 获取模式串的next数组(KMP的核心)
    def getNext(next,s):
        next[0] = 0
        j = 0
        # j 指向前缀末尾位置, i 指向后缀末尾位置
        # 采用0 1 0 1 2 0
        # 每次回退取前一位的next值
        for i in range(1, len(s)):
            while j > 0 and s[i] != s[j]:  # 前缀和后缀不相等,回退
                j = next[j - 1]
            if s[i] == s[j]:  # 上面退出while可能是因为j == 0或者s[i] == s[j],所以这里还要再判断一下
                j += 1
            next[i] = j  # next[i]的值就是j,前缀的长度

    next = [-1] * len(needle)
    getNext(next,needle)
    i,j = 0,0
    while i < len(haystack) and j < len(needle):
        while j > 0 and haystack[i] != needle[j]:
            j = next[j - 1]
        if haystack[i] == needle[j]: # 这里要么是中途能续上(如aab),要么模式串从头开始
            j += 1
        i += 1
    return i - j if j == len(needle) else -1

7.重复的子字符串(2)

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

这道题绝对不止简单题的难度

移动匹配

字符串:s+s(掐头去尾)

模式串:s

def repeatedSubstringPattern(self, s: str) -> bool:
    n = len(s)
    def getNext(next,st):
        j = 0
        for i in range(1,len(st)):
            while j > 0 and st[i] != st[j]:
                j = next[j - 1]
            if st[i] == st[j]:
                j += 1
            next[i] = j
    next = [0]*n
    getNext(next,s)
    i,j = 0,0
    # h:匹配串  s:模式串
    # 原字符串掐头去尾
    h = (s+s)[1:2*len(s)-1]
    while i < len(h) and j < len(s):
        while j > 0 and s[j] != h[i]:
            j = next[j - 1]
        if s[j] == h[i]:
            j += 1
        i += 1
    return j == len(s)
最小重复字串

ababab ab

ab ababab

next: 0 0 1 2 3 4 5 6

若next[n-1]!=0 && len(s)%(len(s)-next[n-1])==0,说明满足题设条件

def repeatedSubstringPattern(self, s: str) -> bool:
    n = len(s)
    def getNext(next,st):
        j = 0
        for i in range(1,len(st)):
            while j > 0 and st[i] != st[j]:
                j = next[j - 1]
            if st[i] == st[j]:
                j += 1
            next[i] = j
    next = [0]*n
    getNext(next,s)

    return True if next[n - 1] != 0 and (n % (n - next[n - 1]) == 0) else False
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值