首页 > 其他分享 >代码随想录二刷字符串

代码随想录二刷字符串

时间:2024-08-04 20:55:42浏览次数:14  
标签:slow 后缀 needle 随想录 len next 二刷 fast 字符串

代码随想录二刷字符串

看leetcode这样一道题目:

在这里插入图片描述

这道题若是用python库函数直接就秒了。但是那这道题就失去了本身的意义。
题目注意事项中也说了输入字符串S可能存在前导空格、尾随空格或者单词间的多个空格。所以首先是对字符串处理。去除其中的空格。这与之前去除数组中去除特定元素是一样的思路。
在这里插入图片描述

所以程序如下:

class Solution:
    def reverseWords(self, s: str) -> str:
        slow = 0
        fast = 0
        s = list(s)
        while fast < len(s):
            if s[fast] != ' ':
                if slow!=0:
                    s[slow] = ' '
                    slow += 1
                while fast < len(s) and s[fast]!=' ':
                    s[slow] = s[fast]
                    slow += 1
                    fast += 1
            else:
                fast += 1
        reversed_s = s[:slow][::-1]
        point = 0
        for i in range(len(reversed_s)+1):
            if i == len(reversed_s) or reversed_s[i] == ' ':
                reversed_s[point:i] = reversed_s[point:i][::-1]
                point = i + 1
        return ''.join(reversed_s)

接下来来看下字符串中的KMP算法。

KMP算法

KMP用途:

KMP主要应用在字符串匹配上。KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。所以如何记录已经匹配的文本内容,是KMP的重点,也是next数组肩负的重任。
在这里插入图片描述
上面手写的原理其实还不够好理解。比如上面匹配到b和f是不匹配的。但是模式串中f之前的字符串和文本串中b之前的事一模一样的。并且aabaa的最长相等前后缀为2。说明文本串不用从开头再去遍历。

构造next数组

构造next数组其实就是计算模式串s,前缀表的过程。 主要有如下三步:

  1. 初始化
  2. 处理前后缀不相同的情况
  3. 处理前后缀相同的情况
    这里用不减一的前缀表:
class Solution:
    def getNext(self, next: List[int], s: str) -> None:
        j = 0
        next[0] = 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

next[i] 表示 i(包括i)之前最长相等的前后缀长度(其实就是j)所以初始化next[0] = j 。
接下来就是处理前后缀不相同的情况:
如果 s[i] 与 s[j+1]不相同,也就是遇到 前后缀末尾不相同的情况,就要向前回退。怎么回退呢?next[j]就是记录着j(包括j)之前的子串的相同前后缀的长度。那么 s[i] 与 s[j+1] 不相同,就要找 j+1前一个元素在next数组里的值(就是next[j])。
前后缀相同的情况:
如果 s[i] 与 s[j + 1] 相同,那么就同时向后移动i 和j 说明找到了相同的前后缀,同时还要将j(前缀的长度)赋给next[i], 因为next[i]要记录相同前后缀的长度。
接下来就来看下leetcode这道题:
在这里插入图片描述
具体程序如下:

class Solution:
    def getNext(self, next: List[int], s: str) -> None:
        j = 0
        next[0] = 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
    
    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) == 0:
            return 0
        next = [0] * len(needle)
        self.getNext(next, 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

标签:slow,后缀,needle,随想录,len,next,二刷,fast,字符串
From: https://www.cnblogs.com/bathwind/p/18342182

相关文章

  • 混合了 UTF-8 字符串和 Unicode 转义序列的字符串统一转化为 UTF-8 编码的字符串
    如果你有一个包含混合了UTF-8字符串和Unicode转义序列的字符串,并希望将它们统一转化为UTF-8编码的字符串,你可以按以下步骤进行操作。此过程涉及区分正常的UTF-8字符串和那些需要解码的Unicode转义序列。示例假设你的字符串包含以下内容:mixed_str="这是一段文本......
  • 模拟实现 srtcat(字符串追加) --浅谈C语言
    strcat描述char*strcat(char*dest,constchar*src)把src所指向的字符串追加到dest所指向的字符串的结尾。声明下面是strcat()函数的声明。char*strcat(char*dest,constchar*src)参数dest--指向目标数组,该数组包含了一个C字符串,且足够容纳追加后的字符......
  • 代码随想录算法训练营day03|203.移除链表元素,707.设计链表,206.反转链表
    203.移除链表元素题目链接:https://leetcode.cn/problems/remove-linked-list-elements/description/我的代码(分头节点和中间节点两种情况操作):/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode():val......
  • 【C语言】字符函数和字符串函数详解
    ......
  • 代码随想录 day 44 最长公共子序列 | 不相交的线 | 最大子序和 | 判断子序列
    最长公共子序列最长公共子序列解题思路本题dp数组的含义是最长公共序列,而后同时遍历两个字符串,遇到相同的字母是公共子序列+1,否则取两个字符串的公共子序列中较长的一个。知识点动态规划,子序列心得没有想到比较两个字符串的公共子序列。我自己是遇到相同字母时将所有后续的......
  • 「字符串」实现Trie(字典树|前缀树)的功能 / 手撕数据结构(C++)
    概述在浏览器搜索栏里输入几个字,就弹出了以你的输入为开头的一系列句子。浏览器是怎么知道你接下来要输什么的?来看看字典树干了什么。字典树是一种高效记录字符串和查找字符串的数据结构。它以每个字符作为一个节点对字符串进行分割记录,节点形成树状结构,在录入或查找时只......
  • 数组和字符串
    数组简介1.LeetCode1991找到数组的中间位置方法1:前缀和classSolution{publicintfindMiddleIndex(int[]nums){inttol=0,s=0;for(intnum:nums)tol+=num;for(inti=0;i<nums.length;i++){......
  • 字符串
    aaa今天字符串专题1)KMP思想是对于每一位求出最长的后缀等于前缀的长度next周期:字符串:【】【】【】【】【不完整周期】【】就是周期有一个周期就是串长减去next,所有周期长度都是最小周期的倍数;如果串不是最小周期的倍数,则这个串没有循环节。【NOI2014动物园】点击......
  • 模拟实现strcmp,判断二个字符串是否相等
    1.判断二个字符串是否相等,可以模仿strcmp.当二个字符串相等的时候ruturn0.,当二个字符串小于时返回为小于0,当二个字符串大于时返回为大于0。const为不可以更改。//方法一intmy_strcmp(constchar*arr1,constchar*arr2){ assert(arr1&&arr2); while(*arr1==*arr2)......
  • 2024-08-03:用go语言,给定一个从 0 开始的字符串数组 `words`, 我们定义一个名为 `isPref
    2024-08-03:用go语言,给定一个从0开始的字符串数组words,我们定义一个名为isPrefixAndSuffix的布尔函数,该函数接受两个字符串参数str1和str2。当str1同时是str2的前缀和后缀时,函数返回true;否则返回false。例如,isPrefixAndSuffix("aba","ababa")返回true,因为"ab......