28、实现strStr()

问题描述

在这里插入图片描述

问题分析

此题有很多解法,直接调用indexOf方法、KMP、BF、BM等等。indexOf方法背离原意;最经典的是KMP解法,效率高,不过过于复杂;于是本题决定采用在实际情况中效果较好且理解简单的算法,即 Sunday 算法。

算法介绍:Sunday算法


解法:Sunday算法

  • Sunday预处理阶段的时间为:O(|∑| + m)
  • 最坏情况下时间复杂度为:O(nm)
  • 平均时间复杂度:O(n)
  • 空间复杂度:O(|∑|)

Java代码

class Solution {
    public int strStr(String haystack, String needle) {
        int n = haystack.length();
        int m = needle.length();

        //特殊情况处理
        if (n < m){
            return -1;
        }
        if (m == 0){
            return 0;
        }

        //构建偏移表(hash)
        int[] shift = new int[256];
        for (int i = 0; i < 256; i++) {
            shift[i] = m + 1;
        }
        for (int i = 0; i < m; i++) {
            int mmm = needle.charAt(i);
            shift[needle.charAt(i)] = m - i;
        }

        //模式串开始位置在主串的哪里
        int index = 0;
        //模式串的当前匹配位置
        int cur;
        while (index <= n-m){
            cur = 0;
            //匹配到一位
            while (haystack.charAt(index + cur) == needle.charAt(cur)){
                cur++;
                //全部匹配成功
                if (cur >= m){
                    return index;
                }
            }
            
            //匹配失败,按照偏移表移位
            //走到末尾的特殊情况
            if (index + m > n-1){
                return -1;
            }
            index += shift[haystack.charAt(index + m)];
        }


        return -1;
    }
}

结果分析

以上代码的执行结果:

执行时间内存消耗
4 ms37.4 MB

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值