java 求最长重复子串_求最长重复子串

本文介绍了如何解决字符串中最长重复子串的问题。首先,详细分析了直观解法的时间复杂度,然后提出利用后缀数组优化,通过排序后缀数组并检测相邻字符串的公共部分来找到最长重复子串。Java实现中,首先初始化后缀数组,接着进行快速排序,最后比较相邻后缀找出最长子串。这种方法的时间复杂度降低到了O(N^2*logN)。
摘要由CSDN通过智能技术生成

一、问题描述

给定一个字符串,求出其最长重复子串

例如:abcdabcd ,最长重复子串是 abcd

最长重复子串可以重叠

例如:abcdabcda ,这时最长重复子串是 abcda ,中间的 a 是被重叠的。

二、分析

1、直观的解法

首先检测长度为 n - 1 的字符串情况,如果不存在重复则检测 n - 2, 一直递减下去,直到 1 。

这种方法的时间复杂度是 O(N * N * N),其中包括三部分,长度纬度、根据长度检测的字符串数目、字符串检测。

2、使用后缀数组

后缀数组:例如对于字符串String str="banana"的后缀数组是a[0]="anana",a[1]="nana",a[2]="ana",a[3]="na",a[4]="a",

改进的方法是利用后缀数组:对一个字符串生成相应的后缀数组后,然后再排序,排完序依次检测相邻的两个字符串的开头公共部分。

这样的时间复杂度为:

1)生成后缀数组 O(N)

2)排序 O(NlogN*N) 最后面的 N 是因为字符串比较也是 O(N)

3)依次检测相邻的两个字符串 O(N * N)

总的时间复杂度是 O(N^2*logN)

三、java实现

分为三步:

第一步:初始化后缀数组

第二步:对后缀数组进行按字典排序

第三步:对后缀数组中相邻元素进行比较,求最长子串

public classMaxSameString {/** 比较两个相邻的字符串*/

public intsameLen(String str1,String str2){int index=0;while(index

index++;

}else{break;

}

}returnindex;

}/** 使用快速排序,对字符串按照字典顺序排列*/

public void quickSort(String[] after,int start,intend){int low=start;int high=end;

String pkey=after[low];while(low0) high--;

after[low]=after[high];while(low

after[high]=after[low];

}

after[low]=pkey;if(start

quickSort(after, low+1, end);

quickSort(after, start, low-1);

}

}/***@paramargs*/

public static voidmain(String[] args) {//TODO Auto-generated method stub

MaxSameString mss=newMaxSameString();

String src="banana";//待处理数组

String[] after=new String[src.length()-1];//后缀数组//第一步:初始化后缀数组

for(int i=0;i

after[i]=src.substring(i+1);

}//第二步:对后缀数组进行按字典排序

mss.quickSort(after, 0,after.length-1);int maxlen=0;int maxi=0;//最长字符串出现在后缀数组中的位置//第三步:对后缀数组中相邻元素进行比较,求最长子串

for(int i=0;imaxlen){

maxlen=tmp;

maxi=i;

}

}

System.out.println("Max length is "+maxlen);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值