LeetCode每日一题 28.实现 strStr()

LeetCode每日一题 28.实现 strStr()

难度:简单(其实不简单,要理解KMP算法)
语言:java

题目内容

实现 strStr() 函数。

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

解题思路

暴力解法比较简单,就是用i遍历haystack直到发现第一位与needle相同,然后开始用j遍历needle,分别为haystack[i+j] 和 nddle[j],直到不同,继续回到i进行遍历,复杂度为O(m*n),因为要两次遍历。代码如下

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        if (m == 0){
            return 0;
        }
        for (int i = 0; i + m <= n; i++) {
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    break;
                }
                else if (j==m-1){
                    return i;
                }
            }
        }
        return -1;
    }
}

另外的解法就是KMP算法,这是我第一次接触到这个算法,但是好像计算机考研的同学是需要学习这个的, 走捷径出国的代价就是很多知识都不知道啊。

KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。

这个以我的水平很难解释得清,我觉得借鉴外部视频会好很多,因为有动态的演示,放三个链接在下面,B站真的是学习宝藏。

KMP算法易懂版

Next函数值的简单计算

Next函数的代码实现(大哥讲得还算清晰)

我觉得看明白这仨,再来看题目就简单多了,其实就是对模式串的一个重复部分的分析,以跳过不必要的匹配部分。
那回到这道题目,可以用KMP算法来解答了,具体代码如下,详细部分见注释。

class Solution {
    public int strStr(String haystack, String needle) {
        if (needle.isEmpty()) return 0;
        int n = haystack.length(), m = needle.length();
        //先构建next函数
        int[] next = new int[m];
        for (int i = 1, j= 0; i<m; i++){
            // i 为后缀末尾,j为前缀末尾(同时也是相同长度)
            while (j>0 && needle.charAt(i) != needle.charAt(j)){
                j = next[j-1];  // 向前一位寻找回退位置
            }
            if (needle.charAt(i) == needle.charAt(j)){
                j++; //匹配相同,向后移动一位,同时更新相同前后缀的长度
            }
            next[i]=j; //更新next数组
        }
        //next函数的回退位置需要看前一位的值,next函数的解法基本类似,可以进行记忆
        //接下来求解题目
        for(int i = 0, j =0; i<n;i++){
            while (j>0 && haystack.charAt(i) != needle.charAt(j)){
                j = next[j-1];
            }
            if (haystack.charAt(i) == needle.charAt(j)){
                j++;
            }
            if(j == m ){
                return i-m+1;
            }
        }
    }
}

私认为,直到这一个KMP算法可以解决相同字符串的问题就好了,死记硬背不是我们想要学习的方向,更多的是使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值