Needle-Haystack

Find the First Occurrence of Needle in Haystack

Problem Statement

Implement a function strStr(haystack, needle) that returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example :

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

Best Data Structure for Solving the Problem

Since we're dealing with string pattern matching, a simple String traversal with two-pointer or substring comparison is efficient here.

Multiple Approaches

Approach 1: Built-in Method (Quick & Easy)

Idea: Use Java's built-in indexOf() function. It's optimized under the hood and handles all edge cases.


public int strStr(String haystack, String needle) { return haystack.indexOf(needle); }

Approach 2: Manual Sliding Window (Interview-Ready)

Idea: Slide a window of size needle.length() across haystack and compare each substring with needle.


class Solution { public int strStr(String haystack, String needle) { int n = haystack.length(); int m = needle.length(); if (m == 0) return 0; for (int i = 0; i <= n - m; i++) { if (haystack.substring(i, i + m).equals(needle)) { return i; } } return -1; } }

 Pro Tip: haystack.substring(i, i + m) creates a new string—so if you want to save memory, use a custom comparison loop instead.

Approach 3: KMP Algorithm (Optimized for Large Strings)

Idea: Use the Knuth-Morris-Pratt (KMP) algorithm to preprocess the needle for efficient pattern matching in O(n + m) time.

class Solution {

    public int strStr(String haystack, String needle) {

        if (needle.length() == 0) return 0;

        int[] lps = buildLPS(needle);

        int i = 0; // pointer for haystack

        int j = 0; // pointer for needle

        while (i < haystack.length()) {

            if (haystack.charAt(i) == needle.charAt(j)) {

                i++;

                j++;

                if (j == needle.length()) {

                    return i - j; // match found

                }

            } else {

                if (j != 0) {

                    j = lps[j - 1]; // fall back

                } else {

                    i++;

                }

            }

        }

        return -1; // no match

    }


    private int[] buildLPS(String pattern) {

        int[] lps = new int[pattern.length()];

        int len = 0;

        int i = 1;


        while (i < pattern.length()) {

            if (pattern.charAt(i) == pattern.charAt(len)) {

                len++;

                lps[i] = len;

                i++;

            } else {

                if (len != 0) {

                    len = lps[len - 1];

                } else {

                    lps[i] = 0;

                    i++;

                }

            }

        }

        return lps;

    }

}

⚠️ Common Mistakes and Pitfalls

  • Forgetting to return 0 when needle is empty

  • Looping until i < haystack.length() instead of i <= haystack.length() - needle.length()

  • Confusing == with .equals() for strings in Java 

  • Not handling edge cases like empty haystack, needle, or both

📊 Time and Space Complexity Analysis

Step        Time Complexity      Space Complexity
Built-in indexOf()        O(n * m) worst        O(1)
Manual Sliding Window        O(n * m)        O(1)
KMP Algorithm        O(n + m)        O(m)

Where n = haystack.length() and m = needle.length().

🌍 Real-World Applications

  • Searching for a keyword in a large document or dataset

  • Autocomplete or search bar functionality

  • DNA or genome pattern matching

  • Log monitoring for specific strings or patterns


I hope you found this article insightful! Keep exploring, keep learning, and don’t forget to check back daily for more exciting problem breakdowns. If you know someone who would benefit from this, share it with them and help them grow too! That’s it for today—see you in the next post!

                                                                                                                                         Signing off!! 

                                                                                                Master DSA One Problem at a Time :)

Comments

Popular posts from this blog

Divisible Drama — Who’s In, Who’s Out?

Trailing Zeros in Factorial – How Many and Why?

Minimum equal sum