实现 strStr()

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1
说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-strstr
思路:非常简单,遍历haystack,找到和needle的第一个字符相等的字符,再构建长度和needle相等的子串,看二者是否相等,相等则说明找到了needle字符串出现的第一个位置。

代码:

class Solution {
    public int strStr(String haystack, String needle) {
        int n=needle.length();//用于记录needle字符串的长度
        if(n==0){//n等于0说明needle是空字符串,返回0
            return 0;
        }
        char cn=needle.charAt(0);//记录needle的第一个字符
        int index=-1;//要返回的索引值,先置为-1
        for(int i=0;i<haystack.length();i++){
            char ch=haystack.charAt(i);
            if(cn==ch){//说明找到了和needle第一个字符相等的字符了
                if(i+n<=haystack.length()){
                     if(needle.equals(haystack.substring(i,i+n))){//说明该子串和needle相等
                        index=i;
                        break;
                    }//end if
                }else{//说明i+n>haystack.length()了,无法截取和needle一样长的子串了
                    break;
                }
            }//end if
        }//end for
        return index;
    }
}
java源码:

/**
* Code shared by String and AbstractStringBuilder to do searches. The
* source is the character array being searched, and the target
* is the string being searched for.
*
* @param source the characters being searched.
* @param target the characters being searched for.
* @param fromIndex the index to begin searching from.
*/
static int indexOf(String source, String target, int fromIndex) {
final int sourceLength = source.length();
final int targetLength = target.length();
if (fromIndex >= sourceLength) {
return (targetLength == 0 ? sourceLength : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetLength == 0) {
return fromIndex;
}

char first = target.charAt(0);
// 计算出最多比较的次数
int max = (sourceLength - targetLength);

for (int i = fromIndex; i <= max; i++) {
// 寻找在source中出现和target第一个字符相等的位置
if (source.charAt(i)!= first) {
while (++i <= max && source.charAt(i) != first);
}

if (i <= max) {
// 找到第一个相等的字符后,从下一个字符开始再比较(下次比较开始的位置)
int j = i + 1;
// 除target第一个字符,剩下字符再比较结束的位置
// 可以理解为:j+(targetLength-1), 即开始的位置+ target剩下要比较字符的长度
int end = j + targetLength - 1;
/* j < end 说明还没有比较完
* j < end && source.charAt(j) == target.charAt(k) 是真说明在还没比较完的情况下比较的字符相等,
* 那么继续循环,直到条件为false
*/
for (int k = 1; j < end && source.charAt(j) == target.charAt(k); j++, k++);

// 上面循环结束时 j刚好等于结束比较的位置,那么就返回上面找到的target第一个字符相等的位置
if (j == end) {
return i;
}
}
}
return -1;
}

作者:mickeyqiong
链接:https://leetcode-cn.com/problems/implement-strstr/solution/yi-xing-dai-ma-de-bei-hou-yuan-ma-wei-wo-men-zuo-l/
来源:力扣(LeetCode)

个人认为max不是计算出来的最多比较次数,而是鉴于target的长度,最多只需要检索到source第max+1个字符就可以了

我的代码与java源码的差距:

1.java源码考虑了max,而我的代码没有体现

2.java源码没有使用substring方法

针对第一点,将我的代码进行改进,如下:

class Solution {
    public int strStr(String haystack, String needle) {
        if(needle.length()==0){
            return 0;
        }
        int index=-1;
        int max=haystack.length()-needle.length();
        char cn=needle.charAt(0);
        for(int i=0;i<=max;i++){
            if(haystack.charAt(i)!=cn){
                continue;
            }
            if(needle.equals(haystack.substring(i,i+needle.length()))){
                index=i;
                break;
            }
        }//end for
        return index;
    }
}
改进后的代码更加简洁,但是用时和原来的代码差不多,也和直接调用indexOf函数的用时差不多。
posted @ 2020-02-11 12:49  xbc121  阅读(128)  评论(0编辑  收藏  举报