# 28. Find the Index of the First Occurrence in a String

## Description

Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "sadbutsad", needle = "sad"
Output: 0
Explanation: "sad" occurs at index 0 and 6.
The first occurrence is at index 0, so we return 0.


Example 2:

Input: haystack = "leetcode", needle = "leeto"
Output: -1
Explanation: "leeto" did not occur in "leetcode", so we return -1.


Constraints:

• 1 <= haystack.length, needle.length <= 104
• haystack and needle consist of only lowercase English characters.

## Solutions

Solution 1: Traversal

We compare the string needle with each character of the string haystack as the starting point. If we find a matching index, we return it directly.

Assuming the length of the string haystack is $n$ and the length of the string needle is $m$, the time complexity is $O((n-m) \times m)$, and the space complexity is $O(1)$.

Solution 2: Rabin-Karp String Matching Algorithm

The Rabin-Karp algorithm essentially uses a sliding window combined with a hash function to compare the hashes of fixed-length strings, which can reduce the time complexity of comparing whether two strings are the same to $O(1)$.

Assuming the length of the string haystack is $n$ and the length of the string needle is $m$, the time complexity is $O(n+m)$, and the space complexity is $O(1)$.

Solution 3: KMP String Matching Algorithm

Assuming the length of the string haystack is $n$ and the length of the string needle is $m$, the time complexity is $O(n+m)$, and the space complexity is $O(m)$.

• class Solution {
public int strStr(String haystack, String needle) {
if ("".equals(needle)) {
return 0;
}

int len1 = haystack.length();
int len2 = needle.length();
int p = 0;
int q = 0;
while (p < len1) {
if (haystack.charAt(p) == needle.charAt(q)) {
if (len2 == 1) {
return p;
}
++p;
++q;
} else {
p -= q - 1;
q = 0;
}

if (q == len2) {
return p - q;
}
}
return -1;
}
}

/////////

func strStr(haystack string, needle string) int {
n, m := len(haystack), len(needle)
sha, target, left, right, mod := 0, 0, 0, 0, 1<<31-1
multi := 1
for i := 0; i < m; i++ {
target = (target*256%mod + int(needle[i])) % mod
}
for i := 1; i < m; i++ {
multi = multi * 256 % mod
}

for ; right < n; right++ {
sha = (sha*256%mod + int(haystack[right])) % mod
if right-left+1 < m {
continue
}
if sha == target && haystack[left:right+1] == needle {
return left
}
sha = (sha - (int(haystack[left])*multi)%mod + mod) % mod
left++
}
return -1
}

• class Solution {
private:
vector<int> Next(string str) {
vector<int> n(str.length());
n[0] = -1;
int i = 0, pre = -1;
int len = str.length();
while (i < len) {
while (pre >= 0 && str[i] != str[pre])
pre = n[pre];
++i, ++pre;
if (i >= len)
break;
if (str[i] == str[pre])
n[i] = n[pre];
else
n[i] = pre;
}
return n;
}

public:
int strStr(string haystack, string needle) {
if (0 == needle.length())
return 0;

vector<int> n(Next(needle));

int len = haystack.length() - needle.length() + 1;
for (int i = 0; i < len; ++i) {
int j = 0, k = i;
while (j < needle.length() && k < haystack.length()) {
if (haystack[k] != needle[j]) {
if (n[j] >= 0) {
j = n[j];
continue;
} else
break;
}
++k, ++j;
}
if (j >= needle.length())
return k - j;
}

return -1;
}
};

• class Solution:
def strStr(self, haystack: str, needle: str) -> int:
n, m = len(haystack), len(needle)
for i in range(n - m + 1):
if haystack[i : i + m] == needle:
return i
return -1


• func strStr(haystack string, needle string) int {
n, m := len(haystack), len(needle)
sha, target, left, right, mod := 0, 0, 0, 0, 1<<31-1
multi := 1
for i := 0; i < m; i++ {
target = (target*256%mod + int(needle[i])) % mod
}
for i := 1; i < m; i++ {
multi = multi * 256 % mod
}

for ; right < n; right++ {
sha = (sha*256%mod + int(haystack[right])) % mod
if right-left+1 < m {
continue
}
if sha == target && haystack[left:right+1] == needle {
return left
}
sha = (sha - (int(haystack[left])*multi)%mod + mod) % mod
left++
}
return -1
}

• function strStr(haystack: string, needle: string): number {
const m = haystack.length;
const n = needle.length;
for (let i = 0; i <= m - n; i++) {
let isEqual = true;
for (let j = 0; j < n; j++) {
if (haystack[i + j] !== needle[j]) {
isEqual = false;
break;
}
}
if (isEqual) {
return i;
}
}
return -1;
}

/////////

function strStr(haystack: string, needle: string): number {
const m = haystack.length;
const n = needle.length;
const next = new Array(n).fill(0);
let j = 0;
for (let i = 1; i < n; i++) {
while (j > 0 && needle[i] !== needle[j]) {
j = next[j - 1];
}
if (needle[i] === needle[j]) {
j++;
}
next[i] = j;
}
j = 0;
for (let i = 0; i < m; i++) {
while (j > 0 && haystack[i] !== needle[j]) {
j = next[j - 1];
}
if (haystack[i] === needle[j]) {
j++;
}
if (j === n) {
return i - n + 1;
}
}
return -1;
}

• /**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function (haystack, needle) {
const slen = haystack.length;
const plen = needle.length;
if (slen == plen) {
return haystack == needle ? 0 : -1;
}
for (let i = 0; i <= slen - plen; i++) {
let j;
for (j = 0; j < plen; j++) {
if (haystack[i + j] != needle[j]) {
break;
}
}
if (j == plen) return i;
}
return -1;
};


• class Solution {
/**
* @param String $haystack * @param String$needle
* @return Integer
*/
function strStr($haystack,$needle) {
$strNew = str_replace($needle, '+', $haystack);$cnt = substr_count($strNew, '+'); if ($cnt > 0) {
for ($i = 0;$i < strlen($strNew);$i++) {
if ($strNew[$i] == '+') {
return \$i;
}
}
} else {
return -1;
}
}
}

• public class Solution {
public int StrStr(string haystack, string needle) {
for (var i = 0; i < haystack.Length - needle.Length + 1; ++i)
{
var j = 0;
for (; j < needle.Length; ++j)
{
if (haystack[i + j] != needle[j]) break;
}
if (j == needle.Length) return i;
}
return -1;
}
}

• impl Solution {
pub fn str_str(haystack: String, needle: String) -> i32 {
let haystack = haystack.as_bytes();
let needle = needle.as_bytes();
let m = haystack.len();
let n = needle.len();
let mut next = vec![0; n];
let mut j = 0;
for i in 1..n {
while j > 0 && needle[i] != needle[j] {
j = next[j - 1];
}
if needle[i] == needle[j] {
j += 1;
}
next[i] = j;
}
j = 0;
for i in 0..m {
while j > 0 && haystack[i] != needle[j] {
j = next[j - 1];
}
if haystack[i] == needle[j] {
j += 1;
}
if j == n {
return (i - n + 1) as i32;
}
}
-1
}
}