字符串比较 kmp算法 Leetcode 28 Leetcode 1392

这里分享下我学习KMP的心得

KMP算法是三位计算机科学家发明的字符串匹配算法。
从暴力逐个比对到最大公共前后缀优化

next数组

假设已经得到next数组,使用数组进行字符串匹配的流程如上,代码如下

const int N = 100010, M = 1000010;
int n, m;
int ne[N];
char s[M], p[N];
{

    for (int i = 1, j = 0; i <= m; i ++ )
    {
        while (j && s[i] != p[j + 1]) j = ne[j];
        if (s[i] == p[j + 1]) j ++ ;
        if (j == n)
        {
            //ok  得到答案
            return 0;
        }
    }
}

//==================================================================
下面我们来进行next数组的计算
Next数组就是计算某个坐标之前的字符串的能匹配的前缀与后缀的长度
本质上就是自己和自己的匹配

int n, m;
int ne[N];
char s[M], p[N];
for (int i = 2, j = 0; i <= n; i ++ )
{
   while (j && p[i] != p[j + 1]) j = ne[j];
   if (p[i] == p[j + 1]) j ++ ;
   ne[i] = j;
}

下面来试试代码实现解决Leetcode 28. 实现 strStr()
地址 https://leetcode-cn.com/problems/implement-strstr/

实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。
如果不存在,则返回  -1 。

说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

示例 1:
输入:haystack = "hello", needle = "ll"
输出:2

示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1

示例 3:
输入:haystack = "", needle = ""
输出:0

提示:
0 <= haystack.length, needle.length <= 5 * 104
haystack 和 needle 仅由小写英文字符组成

解答 使用kmp算法解决该题

class Solution {
public:
	int ne[50010];
	int strStr(string haystack, string needle) {
		if (needle.empty()) return 0;
		memset(ne, 0, sizeof ne);
		int m = haystack.size();
		int n = needle.size();
		haystack.insert(haystack.begin(), '#');
		needle.insert(needle.begin(), '#');

		for (int i = 2, j = 0; i <= n; i++)
		{
			while (j && needle[i] != needle[j + 1]) j = ne[j];
			if (needle[i] == needle[j + 1]) j++;
			ne[i] = j;
		}

		for (int i = 1, j = 0; i <= m; i++)
		{
			while (j && haystack[i] != needle[j + 1]) j = ne[j];
			if (haystack[i] == needle[j + 1]) j++;
			if (j == n)
			{
				return i - n;
			}
		}

		return -1;
	}
};

Leetcode 1392 最长快乐前缀
地址 https://leetcode-cn.com/problems/longest-happy-prefix/

「快乐前缀」是在原字符串中既是 非空 前缀也是后缀(不包括原字符串自身)的字符串。
给你一个字符串 s,请你返回它的 最长快乐前缀。
如果不存在满足题意的前缀,则返回一个空字符串。

示例 1:
输入:s = "level"
输出:"l"
解释:不包括 s 自己,一共有 4 个前缀("l", "le", "lev", "leve")和 4 个后缀("l", "el", "vel", "evel")。
最长的既是前缀也是后缀的字符串是 "l" 。

示例 2:
输入:s = "ababab"
输出:"abab"
解释:"abab" 是最长的既是前缀也是后缀的字符串。题目允许前后缀在原字符串中重叠。

示例 3:
输入:s = "leetcodeleet"
输出:"leet"

示例 4:
输入:s = "a"
输出:""
 

提示:
1 <= s.length <= 10^5
s 只含有小写英文字母

解法 求最长的公共前缀后缀 就是kmp中next数组的过程

class Solution {
public:
    int ne[100010];
    string longestPrefix(string s) {
        int n = s.size();
        s.insert(s.begin(), '#');
        memset(ne, 0, sizeof ne);
        for (int i = 2, j = 0; i <= n; i++)
		{
			while (j && s[i] != s[j + 1]) j = ne[j];
			if (s[i] == s[j + 1]) j++;
			ne[i] = j;
		}

        int len = ne[s.size()-1];

        return s.substr(1,len);

    }
};

我的视频题解空间

posted on   itdef  阅读(101)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
历史上的今天:
2020-09-19 LeetCode 404. 左叶子之和 树遍历

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示