最近更新于 2023-07-22 00:42

题目

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

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-strstr
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析及实现

这里是从算法的角度考虑问题,所以直接使用内置函数的方式就不考虑了,做出来也没有意义。

  • 暴力
int strStr(char * haystack, char * needle)
{
    if (strlen(needle) == 0)
    {
        return 0;
    }

    int haystack_len = strlen(haystack);
    int needle_len = strlen(needle);

    for (int i = 0; i <= haystack_len - needle_len; ++i)
    {
        static int j;
        for (j = 0; j < needle_len; ++j)
        {
            if (haystack[i + j] != needle[j])
            {
                break;
            }
        }
        if (j == needle_len)
        {
            return i;
        }
    }
    return -1;
}

0 ms 是不可能等于 0 的,可能测试例子数量少,已经被四舍五入为 0 ms 了。

  • KMP 算法
void kmp_init(const char *s, int *prefix, size_t size) {
    prefix[0] = 0;
    for (size_t i = 1; i < size; ++i) {
        if (s[i] == s[prefix[i - 1]])
            prefix[i] = prefix[i - 1] + 1;
        else {
            int j = i - 1;
            while (prefix[j] > 0 && s[prefix[j]] != s[i])
                j = prefix[j] - 1;
            if (prefix[j] > 0)
                prefix[i] = prefix[j] + 1;
            else {
                prefix[i] = (s[i] == s[0]);
            }
        }
    }
}

int strStr(const char *src, const char *dest) {
    if (!dest || !src)
        return -1;
    if (!*dest)
        return 0;
    size_t size = strlen(dest);
    int *prefix = malloc(sizeof(int) * size);
    kmp_init(dest, prefix, size);
    size_t i, j;
    for (i = j = 0; src[i] && j < size; ++i) {
        if (dest[j] == src[i]) {
            ++j;
        }
        else if (j) {
            while (prefix[j - 1] > 0 && dest[prefix[j - 1]] != src[i])
                j = prefix[j - 1];
            if (prefix[j - 1] > 0) {
                j = prefix[j - 1] + 1;
            }
            else {
                j = (dest[0] == src[i]);
            }
        }
    }
    free(prefix);
    if (j < size)
        return -1;
    return i - size;
}