Top Interview 150
The problem asks us to find the first occurrence of a substring (needle) in a string (haystack) efficiently. Letβs break it down Find the Index of the First Occurrence in a String and solve it using multiple approaches, including a manual implementation.
π Problem Description
Given two strings needle and haystack:
- Return the index of the first occurrence of
needleinhaystack. - Return
-1ifneedledoes not exist inhaystack.
π‘ Examples
Example 1
Input: haystack = "sadbutsad", needle = "sad"
Output: 0
Explanation: "sad" appears first at index 0.
Example 2
Input: haystack = "leetcode", needle = "leeto"
Output: -1
Explanation: "leeto" is not part of "leetcode".
π JavaScript Solution
Approach 1: Built-in indexOf() (Quick and Simple)
If allowed to use JavaScriptβs built-in methods, the indexOf method provides a straightforward solution.
var strStr = function(haystack, needle) {
return haystack.indexOf(needle);
};
Approach 2: Manual Sliding Window (Efficient and Interview Friendly)
To implement this manually, we can use a sliding window approach:
- Traverse the
haystackwith a window of size equal toneedle.length. - Compare the substring in the current window with needle.
- If a match is found, return the starting index of the window.
Implementation
var strStr = function(haystack, needle) {
const n = haystack.length;
const m = needle.length;
for (let i = 0; i <= n - m; i++) {
if (haystack.slice(i, i + m) === needle) {
return i;
}
}
return -1;
};
π How It Works
-
Window Size:
- The window size is equal to the length of
needle(m). - Iterate through the
haystackwhile maintaining a sliding window of sizem.
- The window size is equal to the length of
-
Compare Substrings:
- For each window, compare the substring (
haystack.slice(i, i + m)) withneedle.
- For each window, compare the substring (
-
Return Result:
- If a match is found, return the starting index of the window (
i). - If no match is found after the loop, return
-1.
- If a match is found, return the starting index of the window (
π Complexity Analysis
- > Time Complexity:
O((nβm+1)β m), wherenis the length ofhaystackand m is the length ofneedle.- Each comparison takes
O(m), and we perform nβm+1 comparisons in the worst case.
- Each comparison takes
- > Space Complexity:
O(1), as no extra data structures are used.
Alternative: Knuth-Morris-Pratt (KMP) Algorithm
The KMP algorithm preprocesses the needle to build a partial match table (LPS array), which allows efficient backtracking and reduces redundant comparisons.
Optimized Implementation (KMP Algorithm)
var strStr = function(haystack, needle) {
const n = haystack.length;
const m = needle.length;
const lps = Array(m).fill(0);
let j = 0;
for (let i = 1; i < m; i++) {
while (j > 0 && needle[i] !== needle[j]) {
j = lps[j - 1];
}
if (needle[i] === needle[j]) {
j++;
}
lps[i] = j;
}
j = 0;
for (let i = 0; i < n; i++) {
while (j > 0 && haystack[i] !== needle[j]) {
j = lps[j - 1];
}
if (haystack[i] === needle[j]) {
j++;
}
if (j === m) {
return i - m + 1;
}
}
return -1;
};
π Complexity Analysis (KMP Algorithm)
- Time Complexity:
O(n+m), where n is the length ofhaystackand m is the length ofneedle.- Preprocessing the LPS array takes
O(m). - The search phase takes
O(n).
- Preprocessing the LPS array takes
- Space Complexity:
O(m), for the LPS array.
π Dry Run
Input: haystack = "sadbutsad", needle = "sad"
Using Sliding Window Approach
β¨ Pro Tips for Interviews
-
Clarify edge cases:
- Empty
needle(should return0). -
needlelonger thanhaystack(should return-1).
- Empty
-
Discuss alternatives:
- Built-in
indexOf()for simplicity. - KMP for optimal efficiency.
- Built-in
π Learn More
Check out the detailed explanation and code walkthrough on my Dev.to post:
π Zigzag Conversion - JavaScript Solution
Which approach would you choose? Letβs discuss below! π

Top comments (1)
Follow Me on GitHub π
If you found this solution helpful, check out more of my projects and solutions on my GitHub profile.
Don't forget to follow for more updates!