CSDN话题挑战赛第1期
活动详情地址:https://marketing.csdn.net/p/bb5081d88a77db8d6ef45bb7b6ef3d7f
参赛话题:Leetcode刷题指南
话题描述:代码能力是一个程序员的基本能力,而除了做项目之外,大家接触到的最常规的提升代码能力的方法基本就是刷题了,因此,加油刷题,冲刺大厂!
创作模板:Leetcode刷题指南
文章目录
- 💎一、实现 strStr()
- 🏆1.题目描述
- 🏆2.原题链接
- 💎二、解题报告
- 🏆1.思路分析
- 🏆2.代码详解
- 方法一:暴力遍历
- 方法二:Rabin-Karp 算法
- 方法三:KMP算法
- 🏆3.KMP
💎一、实现 strStr() 🏆1.题目描述
🏆2.原题链接判断一个字符串是不是另一个字符串的子串,子串出现的第一个位置。不存在就返回-1
输入:haystack = “hello”, needle = “ll”
输出:2
💎二、解题报告 🏆1.思路分析https://leetcode.cn/problems/implement-strstr/
🔑思路1:最简单的方法就是暴力遍历,遍历haystack 所有长度和needle 相同的子串, 时间复杂度O(n * m)
找子串这么经典的字符串匹配问题,怎么能只会暴力遍历呢?
🔑思路2:Rabin-Karp算法, 具体算法原理,已经更多练习可以看我这篇博文:https://blog.csdn.net/weixin_44179010/article/details/122081259
终极经典,不好记,不好理解,但是却很牛逼的算法。
🏆2.代码详解 方法一:暴力遍历🔑思路3:KMP算法, 等会会给出详解
借助两个库函数可以拿到100%, 但是原因是测试用例的问题。 这个时间复杂度O(m * n) 还是比较大的
for(int i = 0; i <= haystack.length() - needle.length(); i++) {
if(haystack.substring(i, i + needle.length()).equals(needle)) return i;
}
return -1;
方法二:Rabin-Karp 算法
主要原理是计算子串Hash值,然后以O(n)的时间复杂度获取到主串长度为m的子串的hash值,hash值相同再比较每个字符是否相同。时间复杂度O(n + m)。 时间100%
代码可能较长,但都很简单,很好理解
public int strStr(String haystack, String needle) {
//Rabin - karp
int MOD = 100000009;
int base = 31; //小写字母共26个,必须是比26大的映射。 选择质数31降低偶然性
int srcLen = haystack.length(), tarLen = needle.length();
//计算最高位权重, 这个必须用 long 防止溢出
long highWeight = 1;
//注意这里只需要乘tarLen - 1 次就行了
for(int i = 0; i < tarLen - 1; i++) {
highWeight = (highWeight % MOD * base) % MOD;
}
//计算子串hash值
long tarHash = 0;
for(int i = 0; i < tarLen; i++) {
tarHash = (tarHash * base % MOD + (needle.charAt(i) - 'a')) % MOD;
}
//System.out.println("highWeight=" + highWeight + ", tarHash=" + tarHash);
//遍历计算主串长度和子串相同的 hash值
long srcHash = 0;
for(int i = 0; i < srcLen; i++) {
srcHash = (srcHash * base % MOD + (haystack.charAt(i) - 'a')) % MOD;
//System.out.println(srcHash);
if(i >= tarLen - 1) {
if(srcHash == tarHash) {
//hash值相同,逐个字母比较
boolean flag = false;
for(int j = 0; j < tarLen; j++) {
if(haystack.charAt(i - tarLen + 1 + j) != needle.charAt(j)) flag = true;;
}
if(!flag) return i - tarLen + 1;
}
//减去最高位的
srcHash = (srcHash - highWeight * (haystack.charAt(i - tarLen + 1) - 'a') % MOD) % MOD;
if(srcHash < 0) srcHash += MOD;
}
}
return -1;
}
方法三:KMP算法
🏆3.KMP待补充…
KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。
核心是next数组, next数组包含的是前缀字符串 和 后缀后缀字符串相同的最大长度
CSDN话题挑战赛第1期
活动详情地址:https://marketing.csdn.net/p/bb5081d88a77db8d6ef45bb7b6ef3d7f
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)