【LeetCode-Java实现】28. Implement strStr()

28. Implement strStr()

题目描述

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example 1:
Input: haystack = “hello”, needle = “ll”
Output: 2
Example 2:
Input: haystack = “aaaaa”, needle = “bba”
Output: -1
Clarification:
What should we return when needle is an empty string? This is a great question to ask during an interview.
For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C’s strstr() and Java’s indexOf().
在haystack字符串中寻找等于needle的子串,返回第一次出现该子串的下标

思路

  1. 暴力查找,即Brute-Force,逐个遍历haystack字符串,直到找到和needle相等的子串
    使用Java库函数substring找子串,超方便!
  2. KMP,比较重要的字符串匹配算法,但算法过程较繁琐

实现

BF

public int strStr(String haystack, String needle) {
        //BF(利用Java中库函数substring寻找匹配的子串)
        int l1=haystack.length();
        int l2=needle.length();
        
        //特殊情况:needle为空串的话,返回0
        if(needle.equals("")) return 0;
        
        int gap=l1-l2;   //gap指haystack和needle字符串长度的差距
        
        //从haystack第一个元素开始找,一直找到最后只剩下needle的长度(hello下标从0找到3,最后剩一个元素留给可能的needle元素)
        for(int i=0;i<=gap;i++){   //如果haystack存在子串等于needle,则返回子串首元素的下标i
            if(haystack.substring(i,i+l2).equals(needle))  return i;    
        }
        return -1;   //不满足上述情况说明不存在子串,返回-1
    }

KMP:
这是几个月前通过的KMP代码,之前好不容易搞懂了KMP,过了几个月又忘了,心痛~

//求最长公共前后缀:逐步判断 i,j位置上的元素是否相同---
//同:   i++,j++(j位置前进),且相应的next[]值=j++                                     
//不同:i++,j看j前面那个元素的next[]值,退回到这个值,退完再比较i,j位置上的元素。。。以此类推  
   public static int[] kmpnext(String needle){
       int[] next=new int[needle.length()];
       try {
			next[0]=0;
		}catch(Exception e) {
			e.getMessage();
		}
       for(int j=0,i=1;i<needle.length();i++){
           while(j>0 && needle.charAt(i) !=needle.charAt(j)){
               j=next[j-1];
           }
           if(needle.charAt(i) ==needle.charAt(j)){
               j++;
           }
           next[i]=j;
       }
       return next;
   }
    
/*从头开始比较,若两个字符串元素 同:i++,j++,继续向后比较
	 *                        不同:不回开头重新比较,而是跳过一段没有必要的匹配---->
	 *                            子串下标 j退回到其next[j-1]这个值即可和  母串上次中断的置 继续比较
	 * 
	 */
    public int strStr(String haystack, String needle) {
         if(needle.length()==0) return 0;
        int[] next=kmpnext(needle);
        try {
			for(int i=0,j=0;i<haystack.length();i++) {
				while(j>0 && haystack.charAt(i) != needle.charAt(j)) {  //两个字符串元素不同,
					j=next[j-1];   //子串下标 j退回到其next[j-1]这个值
				}
				if(haystack.charAt(i) == needle.charAt(j)) {
					j++;
				}
				if(j==needle.length()) {   //如果比较到了子串最后一个字符,即比较结束了
				return i-j+1;  //返回子串在母串中第一次出现的位置下标
				}
			}
		}catch(Exception e) {
			e.getMessage();
		}
        return -1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值