leetcode-字符串【6,7KMP】

本文介绍了如何通过Python解决LeetCode中关于字符串反转、替换空格、单词反转、字符串旋转等经典问题,以及KMP算法的应用实例。涉及版本号比较、字符串变形、最长公共前缀验证和IP地址验证。深入探讨了字符串处理技巧和算法思想。
摘要由CSDN通过智能技术生成

1、字符串反转

344 字符串反转
方法一:语言特性

	…
	s[:] = s[::-1]
    return s 

2、字符串反转II(done)

541 字符串反转II

class Solution:
    def reverseStr(self, s: str, k: int) -> str:
        t = list(s)
        for i in range(0, len(t), 2 * k):
            t[i: i + k] = reversed(t[i: i + k])
        return "".join(t)

3、替换空格

5 替换空格
方法一:语言特性

return s.replace(' ', "%20")

方法二:遍历

class Solution:
    def replaceSpace(self, s: str) -> str:
        res = []

        for i in s:
            if i == " ":
                res.append("%20")
            else:
                res.append(i)
        return "".join(res)

4、反转字符串里的单词

151 反转字符串里的单词

class Solution:
    def reverseWords(self, s: str) -> str:
        return " ".join(reversed(s.split()))

5、左旋转字符串

58 左旋转字符串

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        return s[n:] + s[:n]

6、重复的子字符串(KMP)

https://space.bilibili.com/525438321

459 重复的子字符串
在一个串中查找是否出现过另一个串(KMP)

  • 如果 s 中没有循环节,那么 ss 中必然有且只有两个 s,此时从 ss[1] 处开始寻找 s ,必然只能找到第二个,所以此时返回值为 len(s)。
  • 当 s 中有循环节时,设循环节为 r,其长度为 l,那么 ss 中必然有 len(s)/l + 1 个 s。因为去掉了第一个 s的第一个字符 (代码中,(s+s).find(s, 1), 是从 ss[1] 处开始 find )所以此时必回找到第二个 s 的起点。
class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        return (s+s).find(s,1) != len(s)

7、实现 strStr(没做KMP)

28. 实现 strStr()

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
         return haystack.find(needle)

8、比较版本号

165. 比较版本号

from itertools import zip_longest

class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        for v1, v2 in zip_longest(version1.split('.'), version2.split('.'), fillvalue=0):
            x, y = int(v1), int(v2)
            if x != y:
                return 1 if x > y else -1
        return 0

双指针法:

class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        n, m = len(version1), len(version2)
        i, j = 0, 0
        while i < n or j < m:
            x = 0
            while i < n and version1[i] != '.':
                x = x * 10 + ord(version1[i]) - ord('0')
                i += 1
            i += 1  # 跳过点号
            y = 0
            while j < m and version2[j] != '.':
                y = y * 10 + ord(version2[j]) - ord('0')
                j += 1
            j += 1  # 跳过点号
            if x != y:
                return 1 if x > y else -1
        return 0

9、字符串变形

BM83 字符串变形

class Solution:
    def trans(self , s: str, n: int) -> str:
        reverse_str = ' '.join(s.split(' ')[::-1])
        return reverse_str.swapcase()

10、最长公共前缀

14. 最长公共前缀
方法一:横向扫描

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if not strs:
            return ""
        
        prefix,count = strs[0],len(strs)
        for i in range(1,count):
            prefix = self.lcp(prefix,strs[i])
            if not prefix:
                break 
        return prefix 
    
    def lcp(self,l1,l2):
        length,index = min(len(l1),len(l2)),0
        while index < length and l1[index] == l2[index]:
            index += 1
        return l1[:index]

方法二:纵向扫描

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if not strs:
            return ""
        
        length, count = len(strs[0]), len(strs)
        for i in range(length):
            #遍历列表第一个str的每个字符
            c = strs[0][i]  
            #依次与剩下的str逐个比较,i == len(strs[j])长度最大为i,strs[j][i] != c 0与j下标i对应的字符不相同
            if any(i == len(strs[j]) or strs[j][i] != c for j in range(1, count)):
                return strs[0][:i] 
        return strs[0]

11、验证IP地址

468. 验证IP地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值