力扣刷题-python-字符串(反转、双指针、KMP)

1.字符串

字符串就是字符串起来。。。

2.反转系列

344. 反转字符串 - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        left, right = 0, len(s) - 1
        
        # 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(right//2)更低
        # 推荐该写法,更加通俗易懂
        while left < right:
            s[left], s[right] = s[right], s[left]
            left  += 1
            right -= 1

541. 反转字符串 II - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def reverseStr(self, s: str, k: int) -> str:

        def reverseString(s: List[str]) -> None:
            left, right = 0, len(s) - 1
            # 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(right//2)更低
            # 推荐该写法,更加通俗易懂
            while left < right:
               s[left], s[right] = s[right], s[left]
               left  += 1
               right -= 1
            return s

        n= len(s)
        lists= list(s)
        for i in range(0,n,2*k):
             lists[i:i+k]= reverseString(lists[i:i+k])      
        return ''.join(lists)

3.双指针

剑指 Offer 05. 替换空格 - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def replaceSpace(self, s: str) -> str:
        n = len(s)
        counter = s.count(' ')  #将里面空格数量读出
        res = list(s)
        res.extend([' '] * counter * 2)

        left, right = len(s)-1, len(res)-1
        for left in range(n-1,-1,-1):
            if res[left] != ' ':
                res[right]= res[left]
                right-=1
            else:
                res[right-2:right+1]='%20'
                right-=3
        return ''.join(res)

151. 翻转字符串里的单词 - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def reverseWords(self, s: str) -> str:
        def reverser(lister,left,right):
             #left, right = 0, len(lister)-1
             while left< right:
                 lister[left], lister[right] = lister[right], lister[left]
                 left+=1
                 right-=1

        #1.删除前后的空格
        left, right = 0, len(s)-1
        while s[left]== ' ': left  += 1   #去除前空格
        while s[right]== ' ':right -= 1   #去除后空格
        lists=[]
        while left<=right:                 #去除中间多余的空格
            if s[left]!=' 'or s[left+1]!=' ':lists.append(s[left])
            left+=1

        #2.反转整个字符串
        reverser(lists,0,len(lists)-1)

        #3.单个字符串反转
        left, right = 0, 0
        while right < len(lists):
            if lists[right]==' ':
                reverser(lists,left,right-1)
                while lists[right+1]==' ':right+=1
                left= right+1
            right+=1
        reverser(lists,left,right-1)

        return ''.join(lists)

剑指 Offer 58 - II. 左旋转字符串 - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        #局部旋转+整体旋转
        def reverser(lister,left,right):
            while left<right:
                lister[left], lister[right] = lister[right], lister[left]
                left+=1
                right-=1

        strls= list(s)
        #局部旋转kn
        reverser(strls,0,n-1)
        reverser(strls,n,len(strls)-1)
        #整体旋转
        reverser(strls,0,len(strls)-1)
        return ''.join(strls)

4.KMP

找到待匹配字符串的前缀表,然后边比对边判断是否满足全部匹配。
很难这块。。。
28. 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        def getNext(s):#得到字符串的前缀表
            next= [0 for _ in range(len(s))]                    #初始化
            next[0]=j=0
            for i in range(1,len(s)):
                while j>0 and s[j]!=s[i]:j=next[j-1]       #处理不相等情况
                if s[j]==s[i]:j+=1                         # 处理相等情况
                next[i]=j                                  #next更新
            return next

        if needle=='':return 0
        next=getNext(needle)  #得到前缀表
        j=0
        for i in range(len(haystack)):
            while  j>0 and haystack[i]!= needle[j]:j= next[j-1]
            if haystack[i]== needle[j]: j+=1
            if j==len(needle):return i-len(needle)+1  #如果找到 返回起始位置
        return -1

459. 重复的子字符串 - 力扣(LeetCode) (leetcode-cn.com)

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        if len(s) == 0:return False
        next = [0]*len(s)
        next[0]= j =0
        for i in range(1,len(s)):
            while j>0 and s[i]!=s[j]: j= next[j-1]
            if s[i]==s[j]: j+=1
            next[i]=j
        if not next[-1] or len(s)%(len(s)-next[-1]):return False
        else: return True

5.总结

字符串基本都可以用双指针做,
KMP是对于重复出现字符做了标记,可以求前缀表,避免重头开始寻找,减少运行的复杂程度。其实自己KMP还没有学的很好,只有在后面再次出现这类题型时候,再次回忆以及学习了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值