力扣 28.实现 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
  • haystackneedle 仅由小写英文字符组成

问题思路

思路1:暴力法

直接让haystack所有长度为m的子串与needle进行匹配。如果匹配成功,则返回相应的下标,如果均无法匹配,则返回-1。

实现代码如下,空间复杂度O(1),时间复杂度O(m.n)。运行时间0 ms。

class Solution {
    public int strStr(String haystack, String needle) {
    	int n = haystack.length();
    	int m = needle.length();
    	if (n < m) {
			return -1;
		} else if (n == 0) {
			return 0;
		}
    	for (int i = 0; i <= n - m; i++) {
			if (haystack.substring(i, i + m).equals(needle)) {
				return i;
			}
		}
    	return -1;
    }
}
思路2:暴力法-优化

同样让所有子串匹配,区别是先进行一次首字符比较,如果一致,则继续匹配剩下的部分;如果首字符不一致,则直接尝试下一个子串。

这里直接放上 java.lang.StringLatin1.indexOf(byte[] value, byte[]str) 库函数的源码。

实现代码如下,空间复杂度O(1),时间复杂度O(m.n)。运行时间0 ms。

    @HotSpotIntrinsicCandidate
    public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
        byte first = str[0];
        int max = (valueCount - strCount);
        for (int i = fromIndex; i <= max; i++) {
            // Look for first character.
            if (value[i] != first) {
                while (++i <= max && value[i] != first);
            }
            // Found first character, now look at the rest of value
            if (i <= max) {
                int j = i + 1;
                int end = j + strCount - 1;
                for (int k = 1; j < end && value[j] == str[k]; j++, k++);
                if (j == end) {
                    // Found whole string.
                    return i;
                }
            }
        }
        return -1;
    }
思路3:Knuth-Morris-Pratt 算法(KMP算法)

由前两个思路我们可以发现,当原串在匹配时如果与匹配串第 i 个位置不一致,原串指针就要回退 i - 1 个单位,然后重新开始比较,这无疑会浪费大量的时间。

那么有没有一种算法可以在不一致时原串指针位置不回退,仍然从当前位置继续比较呢?

答案是肯定的,这就是KMP算法。该算法通过在发生不一致时,利用已匹配子串具有的相同前后缀的特点,减少回退的长度,加速下一次的匹配。

例如原串 abcabe 在 e 处不一致时,因为已匹配的字串“abcab”有相同的前后缀“ab”,只需将指针移到"ab"的下一个位置,然后从匹配串的 c 处、原串的 e 处继续比较即可。

该算法空间复杂度O(m),时间复杂度O(m+n)。

算法详细可参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值