Leetcode刷题116-28. 实现strStr()(C++最简单实现详细解法!!!)

本文详细解析了如何使用C++实现LeetCode上的strStr()函数,包括简单的暴力解法和优化算法如KMP与Sunday算法,旨在帮助理解字符串匹配原理。
摘要由CSDN通过智能技术生成

Come from : [https://leetcode-cn.com/problems/implement-strstr/]

1.Question

Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1 :

Input: haystack = "hello", needle = "ll"
Output: 2

Example 2 :

Input: haystack = "aaaaa", needle = "bba"
Output: -1

Clarification:
What should we return when needle is an empty string? This is a great question to ask during an interview.

For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C’s strstr() and Java’s indexOf().

2.Answer

easy类型题目。。。

AC代码如下(定义两个辅助指针变量,暴力解法):

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.size() == 0) return 0;
        if(haystack.size() == 0) return -1;
        int h_pointer = 0;
        int n_pointer = 0;
        while(h_pointer < haystack.size())
        {
            if(haystack[h_pointer] == needle[n_pointer])
            {
                ++h_pointer;
                ++n_pointer;
                if(n_pointer == needle.size())
                {
                      return h_pointer-n_pointer;
                }
            }
            else
            {
                h_pointer = h_pointer - n_pointer + 1;
                n_pointer = 0;
            }
        }
        return -1;
    }
};

3.大神解答

方法1:速度排名第一(KMP算法 时间复杂度O(M+N))
关于KMP算法的介绍见:1. kmp算法1
2. kmp算法2

class Solution {
    vector<int> next;
    inline void updateNextTable(string &needle){
        next.resize(needle.size());
        next[0] = -1;
        if(next.size()>1){
            next[1] = 0;
        }
        int pi = 1;
        int pj = 0;
        while(pi < next.size()-1)
        {
            if(pj == -1 || needle[pi] == needle[pj] ){
                next[++pi] = ++pj; 
            }
            else{
                pj = next[pj];
            }
        }
    }
public:
    int strStr(string haystack, string needle) {//KMP
        if(needle.size() == 0){
            return 0;
        }
        updateNextTable(needle);
        if(haystack.size() == 0){
            return -1;
        }
        int pi=0,pj=0;
        while(pi<haystack.size() && pj<(int)needle.size())
        {
            if(pj == -1 || haystack[pi] ==needle[pj] ){
                ++pi;
                ++pj;
            }
            else{
                pj = next[pj];
            }
        }
        if(pj == needle.size())
        {
            return pi - pj;
        }
        return -1;
    }
};

方法2:sunday算法(时间复杂度 最坏为O(M*N) 平均复杂度为O(N))
字符串匹配——Sunday算法

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.empty())
            return 0;
        
        int slen=haystack.size();
        int tlen=needle.size();
        int i=0,j=0;//i指向源串首位 j指向子串首位
        int k;
        int m=tlen;//第一次匹配时 源串中参与匹配的元素的下一位
        
        for(;i<slen;)
        {
            if(haystack[i]!=needle[j])
            {
                for(k=tlen-1;k>=0;k--)//遍历查找此时子串与源串[i+tlen+1]相等的最右位置
                {
                    if(needle[k]==haystack[m])
                        break;
                }
                i=m-k;//i为下一次匹配源串开始首位 Sunday算法核心:最大限度跳过相同元素
                j=0;//j依然为子串首位
                m=i+tlen;//m为下一次参与匹配的源串最后一位元素的下一位
                if(m>slen)//当下一次参与匹配的源串字数的最后一位的下一位超过源串长度时
                    return -1;
            }
            else
            {
                if(j==tlen-1)//若j为子串末位 匹配成功 返回源串此时匹配首位
                    return i-j;
                i++;
                j++;
            }
        }
        return -1;//当超过源串长度时 
    }
};

作者:2227
链接:https://leetcode-cn.com/problems/two-sum/solution/c5chong-jie-fa-ku-han-shu-bfkmpbmsunday-by-2227/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.我的收获

字符串匹配算法。。。

2019/7/6 胡云层 于南京 116

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值