LeetCode – Implement strStr() (Java)

Problem:

Implement strStr().

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Java Solution 1 - Naive

public int strStr(String haystack, String needle) {
    if(haystack==null || needle==null)    
        return 0;
 
    if(needle.length() == 0)
        return 0;
 
    for(int i=0; i<haystack.length(); i++){
        if(i + needle.length() > haystack.length())
            return -1;
 
        int m = i;
        for(int j=0; j<needle.length(); j++){
            if(needle.charAt(j)==haystack.charAt(m)){
                if(j==needle.length()-1)
                    return i;
                m++;
            }else{
                break;
            }
 
        }    
    }   
 
    return -1;
}

Java Solution 2 - KMP

Check out this article to understand KMP algorithm.

public int strStr(String haystack, String needle) {
        if(haystack==null || needle==null)    
            return 0;
 
	int h = haystack.length();
	int n = needle.length();
 
	if (n > h)
		return -1;
	if (n == 0)
		return 0;
 
	int[] next = getNext(needle);
	int i = 0;
 
	while (i <= h - n) {
		int success = 1;
		for (int j = 0; j < n; j++) {
			if (needle.charAt(0) != haystack.charAt(i)) {
				success = 0;
				i++;
				break;
			} else if (needle.charAt(j) != haystack.charAt(i + j)) {
				success = 0;
				i = i + j - next[j - 1];
				break;
			}
		}
		if (success == 1)
			return i;
	}
 
	return -1;
}
 
//calculate KMP array
public int[] getNext(String needle) {
	int[] next = new int[needle.length()];
	next[0] = 0;
 
	for (int i = 1; i < needle.length(); i++) {
		int index = next[i - 1];
		while (index > 0 && needle.charAt(index) != needle.charAt(i)) {
			index = next[index - 1];
		}
 
		if (needle.charAt(index) == needle.charAt(i)) {
			next[i] = next[i - 1] + 1;
		} else {
			next[i] = 0;
		}
	}
 
	return next;
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • Ganesh

    I am kind of beginner in java, I approached in this way, It was accepted but can someone suggest me any possible mistake in this one.
    public class Solution {
    public int strStr(String haystack, String needle) {
    if(haystack==null || needle==null)
    return 0;

    if(needle.length() == 0)
    return 0;
    if(haystack.contains(needle))
    {
    return haystack.indexOf(needle);
    }
    else
    return -1;
    }
    }

  • The Awesome Guy

    the getNext method to compute KMP array is wrong.
    For this pattern “aabaabaaa” array should be {0,1,0,1,2,3,4,5,2}, but the above code gives {0,1,0,1,2,3,4,5,6}

  • Pooja Hkl

    My implementation:


    public static int strStr(final String haystack, final String needle) {
    if(haystack == null || needle == null){
    return -1;
    }

    if(needle.length() == 0){
    return -1;
    }

    int j=0;
    int nextIndex=-1;
    boolean flag = false;
    int k = haystack.length() - needle.length();
    for(int i=0; i<=k; ){
    int m=i;
    for(j=0; j 0 && haystack.charAt(m) == needle.charAt(0) && !flag){
    nextIndex = m;
    flag = true;
    }
    m++;
    }else{
    break;
    }

    }

    if(j == needle.length()){
    return i;
    }

    if(flag){
    i = nextIndex;
    flag = false;
    }else{
    if(j!=0)
    i = i+j;
    else
    i = i+1;
    }
    }

    return -1;
    }

  • Tom Dawn

    public class Solution {
    public int strStr(String haystack, String needle) {
    if(haystack==null || needle==null)return 0;
    if(needle.length() == 0)return 0;

    for(int i=0;i<haystack.length()-needle.length()+1;i++){
    if(haystack.substring(i,i+needle.length()).equals(needle))return i;
    }
    return -1;
    }
    }

  • newapp

    yes that’s correct. I always tend to use substring to solve this kind of problem because substring is so fast, concise and accurate. No need to deal with char in Java.

  • Akshay Bapat

    //NlogN Solution: Variation of Merge Sort

    public void strStr(String haystack, String needle){

    strStr(haystack,needle,0,haystack.length());

    }

    public void strStr(String haystack, String needle, int low, int high){

    //Error check
    if(haystack == null || needle == null)
    return ;

    // Terminating condition

    if(low >= high)
    return ;

    int l = low, h = high;

    // Divide and conquer
    while(low < high) {

    int mid = (low + high) / 2;

    strStr(haystack, needle, low, mid);
    strStr(haystack, needle, mid + 1, high);

    low++;

    }

    //Get all haystack substrings from left to right and compare with needle
    for(int i=l; i=l;j–){

    if (haystack.substring(l, j).equalsIgnoreCase(needle)) {

    System.out.println(“Found ” + needle + ” in ” + haystack);

    //Found Match! No need for further checking!
    System.exit(0);
    }
    }

    }

  • public class NeedleInHaystack {

    public int find(String haystack, String needle) {
    if (needle == null || haystack == null) {
    throw new IllegalArgumentException();
    }

    if (“”.equals(needle)) {
    return 0;
    }

    for (int i = 0; i <= haystack.length() – needle.length(); i++) {
    if (haystack.charAt(i) == needle.charAt(0)) {
    if (compare(haystack, i, needle)) {
    return i;
    }
    }
    }

    return -1;
    }

    private boolean compare(String haystack, int index, String needle) {
    for (int i = 0; i < needle.length(); i++, index++) {
    if (needle.charAt(i) != haystack.charAt(index)) {
    return false;
    }
    }

    return true;
    }

    }

  • Kaushik Ghosh

    public static boolean strStr(String haystack, String needle) {

    char[] big = haystack.toCharArray();

    char[] small = needle.toCharArray();

    if(big.length ==0 || small.length == 0) return false;

    char firstChar = small[0];

    //find the first character of needle in the haystack by doing linear scan

    for(int j =0; j < big.length; j ++) {

    if(big[j] == firstChar) {

    //check if remaining consecutive characters match continuously

    if(matchRest(big, small, j+1)) {

    System.out.println(j); // matched at position j

    return true;

    }

    }

    }

    // sorry no match

    return false;

    }

    private static boolean matchRest(char[] big, char[] small,int sBig) {

    int i, j;

    // always start from position 1 of needle since position 0 is guranteed to be matched

    // start with position passed for haystack and make sure to stop before either buffers runs out

    for(i=1, j = sBig; (i< small.length) && (j< big.length); i++, j++) {

    if(big[j] != small[i]) return false;

    }

    // if tail of haystack has a subset of needle then its not a match

    if(j == big.length && i < small.length)

    return false;

    else

    return true;

    }

  • Wally Osmond

    Is this not overly complex with two loops and multiple counters? Perhaps my solution isn’t right and I’m missing something but it seems to work with a one line for loop if you declare your iterator right to not go over the bounds of the array. If you have less space on the end than the needle the needle isn’t there correct? Apologies for crappy formatting.

    Cheers.

    public static String strSTR(String haystack, String needle) {

    if(needle == null || haystack == null)

    return null;

    int nLen=needle.length();

    for(int i=0;i<haystack.length()-nLen;i++){
    if(haystack.substring(i,i+nLen).equals(needle))
    return haystack.substring(i,haystack.length());
    }

    return null;

    }

  • gd

    you do not need “j < needleLen && k < haystackLen " in the "while (j < needleLen && k < haystackLen && needle.charAt(j) == haystack.charAt(k))"

  • Kishore

    After the end of the while loop, you can add i += j; Since you have already gone through j characters after the begining of i.

  • tia

    You have to check if a String == null before call length(), otherwise it will throw NullPointerException