Cover image for Interview Classic 150 Questions P28 Find the Index of the First Occurrence in a String

Interview Classic 150 Questions P28 Find the Index of the First Occurrence in a String

Words 561
Views
Visitors

Timeline

Timeline

2025-10-06

init

KMP

Problem:

Actually, you can directly use the string.find function in C++ to compute it.

1234567
#include <string>using std::string;class Solution {public:  int strStr(string haystack, string needle) { return haystack.find(needle); }};

But obviously this problem tests KMP:

123456789101112131415161718192021222324252627282930313233343536373839
class Solution {public:    int strStr(string s, string p) {        int n = s.size(), m = p.size();        int i, j;        if(m == 0)             return 0;        vector<int> next(m, 0); // next[i] = the length of the longest common prefix and suffix of p[0..i]        // Build the next array        j = 0; // Current longest prefix-suffix length        for(i = 1; i < m; i++){ // Start from 1, because at least two characters are needed to compute the prefix and suffix            while(j > 0 && p[i] != p[j])                j = next[j - 1]; // Fall back to the next best            if(p[i] == p[j])                j++;            next[i] = j;        }        // Match        j = 0; // The current position in the pattern string p        for(i = 0; i < n; i++){            while(j > 0 && s[i] != p[j])                j = next[j - 1];            if(s[i] == p[j])                j++;            if(j == m)                return i - m + 1;        }        return -1;    }};

Example of solving the next array

We use the most classic pattern string:

1
p = "ababaca"

Index:

12
index: 0 1 2 3 4 5 6p    : a b a b a c a

We need to findnext[i]

1
next[i] = p[0..i] 的最长相同前后缀长度

Prefix: starts from the beginning
Suffix: ends at the end (but cannot equal the entire string)

Initialize

12
next[0] = 0j = 0

Because: “a” has no prefix and suffix


i = 1

12
p[1] = bp[j] = p[0] = a

Compare:b != a, becausej = 0, cannot fall back any further.

1
next[1] = 0

Current:

1
next = [0,0]

i = 2

12
p[2] = ap[j] = p[0] = a

Match successful:

12
j++j = 1

So:

1
next[2] = 1

Current:

1
next = [0,0,1]

Explanation:

123456
aba前缀: a ab后缀: a ba最长相同 = a长度 = 1

i = 3

12
p[3] = bp[j] = p[1] = b

Match:

123
j++j = 2next[3] = 2

Current:

1
next = [0,0,1,2]

Explanation:

12345
abab前缀: a ab aba后缀: b ab bab最长 = ab

i = 4

12
p[4] = ap[j] = p[2] = a

Match:

123
j++j = 3next[4] = 3

Current:

1
next = [0,0,1,2,3]

Explanation:

12
ababa最长前后缀 = aba

i = 5 (key backtrack)

12
p[5] = cp[j] = p[3] = b

Mismatch:

1
c != b

Start backtracking:

123
j = next[j-1]j = next[2]j = 1

Continue comparing:

12
p[5] = cp[1] = b

Still mismatch:

123
j = next[j-1]j = next[0]j = 0

Now: j = 0 Stop.

1
next[5] = 0

Current:

1
next = [0,0,1,2,3,0]

i = 6

12
p[6] = ap[j] = p[0] = a

Match:

123
j++j = 1next[6] = 1

Final result

123
p = a b a b a c ai = 0 1 2 3 4 5 6next = 0 0 1 2 3 0 1
Loading comments…