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;
}

20 thoughts on “LeetCode – Implement strStr() (Java)”

  1. X Vibrating series:This series is mainly based on vibrating automatic masturbators. The super strong vibration can bring strong stimulation to your penis, combined with other functions and structures, it can be used as a good penis enhancement trainer and erection stimulatorfor ED, which is beneficial to help men enhance their sexual function.

  2. Perhaps an easier to understand naive solution:


    int strStr(String haystack, String needle)
    {
    if (haystack == null || needle == null) throw new IllegalArgumentException(“Null input”);

    if (needle.isEmpty()) return 0;

    for(int i = 0 ; i < haystack.length() - needle.length() ; ++i)
    {
    boolean strStr = true;

    for(int j = 0 ; j < needle.length() ; j++)
    {
    if (haystack.charAt(i+j) != needle.charAt(j))
    {
    strStr = false;
    break;
    }
    }

    if (strStr) return i;
    }

    return -1;
    }

  3. private static int findNeedle(String n, String h){
    if(h==null ||n==null || h.length()<=n.length()) return -1;
    int nIndex=0;
    for (int i=0;i=n.length()){
    return i;
    }
    }else if(h.length()-i<n.length()){
    return -1;
    }else{
    nIndex=0;
    }
    }
    return -1;
    }


  4. Write tests and find bugs, if any, in the the search method below.
    public class SearchClass
    {
    Public static String search(String haystack[], String needle)
    {
    int index;
    for(index=0;index<haystack.length;index+=1)
    {
    if(needle==haystack[index])
    {
    break;
    }
    }
    return haystack[index];
    }
    }

  5. while going through the pdf version of program creek. I found a small error in the above KMP code. While generating the KMP array, in the method getNext(),

    the line,

    next[i] = next[i-1] + 1;

    should actually be,

    next[i] = index + 1;

    I got this solution accepted on LeetCode.

  6. My solution which is accepted on LeetCode:

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

    if (needle == null || haystack == null)
    return -1;
    if (needle.length() > haystack.length())
    return -1;

    int nlength = needle.length();

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

    return -1;

    }

  7. 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;
    }
    }

  8. 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}

  9. 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;
    }

  10. 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;
    }
    }

  11. 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.

  12. //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);
    }
    }

    }

  13. 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;
    }

    }

  14. 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;

    }

  15. 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;

    }

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

  17. 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.

Leave a Comment