程序员代码面试指南刷题--第九章.KMP算法

题目描述
给定两个字符串str和match,长度分别为N和M。实现一个算法,如果字符串str中含有子串match,则返回match在str中的开始位置,不含有则返回-1
若出现了多次,则按照升序输出所有出现位置
[要求]
时间复杂度为O(n)
输入描述:

第一行一个字符串str
第二行一个字符串match

输出描述:

输出若干个数,分别为match在str中出现的位置,从0开始标号。
若不存在输出-1

示例1

输入

acbc
bc

输出

2

示例2

输入

acbc
bcc

输出

-1

示例3

输入

ababab
ab

输出

0 2 4

解法一:KMP

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s1 = br.readLine().trim();
        String s2 = br.readLine().trim();
        match(s1,s2);
    }
    public static void match(String s1,String s2){
        if(s1==null||s2==null||s1.length()<s2.length()||s2.length()<1){
            return;
        }
        StringBuilder sb = new StringBuilder();
        char[] arr1 = s1.toCharArray();
        char[] arr2 = s2.toCharArray();
        int[] next = getNext(arr2);
        int l1 = 0;
        int l2 = 0;
        while(l1<s1.length()&&l2<s2.length()){
            if(arr1[l1]==arr2[l2]){
                l1++;
                l2++;
            }else if(next[l2]>=0){
                l2 = next[l2];
            }else{
                l1++;
            }
            if(l2==s2.length()){
                sb.append((l1-l2)+" ");
                l2 = 0;
            }
        }
        if(sb.length()==0) sb.append("-1");
        System.out.println(sb.toString().trim());
    }
    public static int[] getNext(char[] s){
        if(s.length==1) return new int[]{-1};
        int [] next = new int[s.length];
        next[0] = -1;
        next[1] = 0;
        int p = 2;
        int cn = 0;
        while(p<s.length){
            if(s[p-1]==s[cn]){
                next[p++] = ++cn;
            }else if(cn>0){
                cn = next[cn];
            }else{
                next[p++] = 0;
            }
        }
        return next;
    }
}
发布了189 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44406146/article/details/105552430