28. 找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 。

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
 

提示:

1 <= haystack.length, needle.length <= 104
haystack 和

needle 仅由小写英文字符组成

解题思路

  1. 先建立next数组,​​​​​​步骤如下:
    1. 固定的next[0]=0
    2. 分别用 i 和 j 指向索引为 0 和 1 的元素,如果needle[i]等于needle[j],i 和 j 一起右边移动且next[i]=j+1
    3. 如果不等,j等于0,令next[i]等于0,j不动,i右移
    4. 如果不等,j不等于0,令j等于next[ i -1 ],直到j等于0或者needle[i]等于needle[j]的情况出现
  2. 接下来可以进行原串与匹配串的匹配
    1. 分别用p1和p2指向原串和匹配串
    2. 若p1和p2指向元素都可以匹配时,p1和p2往后移动一位
    3. 然后再当匹配串第一个元素匹配不上时,说明原串中对应匹配串的当前元素直接淘汰掉,当前元素后移一位
    4. 然后再当匹配串除了第一个以外的元素匹配不上时,匹配串当前元素的上一个元素的next数组值指出有几个后缀,相对应的就有几个前缀,前缀下一个元素与原串的当前元素开始下一轮匹配
public int strStr(String haystack, String needle) {
        int r=1,l=0;
        String needles[]=needle.split("");
        int next[]=new int[needles.length];
        next[0]=0;
        while(r<needles.length){
            if(needles[r].equals(needles[l])){
                next[r]=l+1;
                r++;
                l++;
            }else{
                while (true){
                    if(l==0){
                        next[r]=0;
                        r++;
                        break;
                    }
                    l=next[l-1];
                    if(needles[r].equals(needles[l])){
                        next[r]=l+1;
                        r++;
                        l++;
                        break;
                    }
                }
            }
        }
        System.out.println(Arrays.toString(next));
        int p1=0,p2=0;
        while (p1<haystack.length()&&p2<needle.length()){
            if(haystack.charAt(p1)==needle.charAt(p2)){
                p1++;
                p2++;
            }else{
                //假设从0开始找适当位置
                if(p2-1<0){
                    p1++;
                    continue;
                }
                p2=next[p2-1];
            }
        }
        if(p2>=needle.length())
            return p1-needle.length();
        return -1;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值