1.KMP算法(一种改进的字符串匹配算法):
KMP计算流程:
假设有两个字符串str1和str2,求str2是否是str1的子串
1.先定义一个str2字符串长度的数组,数组中存放的为最长前缀后缀匹配数,其中第一个为-1,第二个为0;
2.str1和str2进行匹配,当碰到不匹配的情况,str2则从开头向后走最长匹配数,再进行匹配;
原因:str1与str2进行匹配,那么不匹配前的数肯定是相等的,因为最长匹配,最后和最前相等,所以最开始的几个数不需要从头匹配,节省时间。
public static int getIndexOf(String m,String n){
if(m==null||n==null||n.length()<1||m.length()<n.length()){
return -1;
}
char[] str1 = m.toCharArray();
char[] str2 = n.toCharArray();
int i=0;
int j=0;
int[] next = getNextArray(str2);
while(i<str1.length&&j<str2.length){
if(str1[i]==str2[j]){
i++;
j++;
}
else if(next[j]==-1){
i++;
}
else{
j = next[j];
}
}
return j ==str2.length? i-j:-1;
}
最长前缀后缀匹配数求解:
1.第一个数为-1,第二个为0;
2.现有i-1,i两个位置,如果i-1位置上的数,是i-1的最长前缀后缀数的下一个数,那么i位置上的最长匹配数为i-1的数+1;
3.如果不是,那么去寻找i-1的最长匹配数的位置j,重复上一步;
4.再不是,则i位置的最长匹配数为0。
public static int[] getNextArray(char[] str2){
if(str2.length==1){
return new int[]{-1};
}
int[] next = new int[str2.length];
next[0]=-1;
next[1]=0;
int cn = 0;
int i=2;
while(i<str2.length){
if(str2[i-1]==str2[cn]){
next[i++] = ++cn;
}
else if(cn>0){
cn = next[cn];
}
else{
next[i++] = 0;
}
}
return next;
}
2.Manacher算法
3. BFPRT算法(求一个数组中第k小或者第k大的数):(arr,k)
3.1 将数组进行分组,每五个分为一组
3.2 将组内元素进行排序,组间不排序
3.3 取出组中的中位数,组成一个新数组
3.4 递归BFPRT算法,BFPRT(new_Arr,new_Arr.length/2); 此时获得的结果是新数组的中位数;
3.5 将此中位数作为荷兰国旗划分的标准。
3.6 荷兰国旗划分最差情况7/10N,原因中位数是新数组的中位数,那么最差情况为1/10个数比它大,新数组中又是中位数,因此至少有3/10N比它大,所以最差是7/10N;
public static int bfprt(int[] arr,int begin,int end,int k){
if(begin==end){
return arr[begin];
}
int pivot = medianOfMedians(arr,begin,end);
int[] index = patation(arr, begin,end,pivot);
if(k>=index[0]&&k<=index[1]){
return arr[k];
}
else if(k>index[1]){
return bfprt(arr,index[1]+1,end,k);
}
else{
return bfprt(arr,0,index[0]-1,k);
}
}
public static int medianOfMedians(int[] arr,int begin,int end){
int num = end-begin+1;
int offset = num%5 ==0?0:1;
int[] mArr = new int[num%5+offset];
for(int i=0;i<mArr.length;i++){
int beginI = begin + i*5;
int endI = begin + 4 ;
mArr[i] = getMedian(arr,beginI,Math.min(end,endI));
}
return bfprt(mArr,0,mArr.length-1,mArr.length/2);
}
public static int getMedian(int[] arr,int begin,int end){
insertionSort(arr,begin,end);
int sum = begin + end;
int mid = sum/2 + sum%2;
return arr[mid];
}
public static void insertionSort(int[] arr,int begin,int end){
for(int i= begin+1;i!=end+1;i++){
for(int j = i;j!=begin;j--){
if(arr[j-1]>arr[j]){
swap(arr,j-1,j);
}
else{
break;
}
}
}
}
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}