KMP算法代码实现记录

private static int kmpDemo(String str1,String str2){
        if (str2==null||str1==null||str1.length()-str2.length()<0){
            return -1;
        }
        //首先构建字符匹配表
        int[] matchTable=getStrMatchTable(str2);
        for (int i = 0,j=0; i < str1.length(); i++) {
            while (j>0&&str1.charAt(i)!=str2.charAt(j)){
                j=matchTable[j-1];
            }
            if(str1.charAt(i)==str2.charAt(j)){
                j++;
            }
            if(j==str2.length()){
                return i-j+1;
            }
        }
        return -1;
    }

  //构建字符匹配表 
    private static int[] getStrMatchTable(String str){
        int[] res=new int[str.length()];
        res[0]=0;
        for (int i = 1,j=0; i < res.length; i++) {
            //当str.charAt(i) != str.charAt(j),需要从res[j-1]获取新的j的位置
            //知道找到二者相等时才退出寻找
            //这是kmp算法的核心
            while (j > 0 && str.charAt(i) != str.charAt(j)) {
                j=res[j-1];
            }
            //当str.charAt(i)==str.charAt(j)满足时,部分匹配值就+
            if(str.charAt(i)==str.charAt(j)){
                j++;
            }
            res[i]=j;
        }
        return res;
    }

======

class Solution {
    int maxK=Integer.MAX_VALUE;
     public int kSimilarity(String A, String B){
        char[] arrA=new char[A.length()];
        char[] arrB=new char[B.length()];
        for (int i = 0; i < arrA.length; i++) {
            arrA[i]=A.charAt(i);
            arrB[i]=B.charAt(i);
        }
        
        doSelect(arrA,arrB,A.length(),0,0);
        return maxK;
    }
    /**
     *
     * @param arrA 字符串A char数组
     * @param arrB 字符串B char数组
     * @param len  char数组的长度(为了方便使用)
     * @param curCount  当前交换的次数
     * @param curIndex  当前交换位置的索引
     */
  private void doSelect(char[] arrA,char[] arrB,int len,int curCount,int curIndex){
        if(curCount>=maxK){//已经不小于最小交换次数,我也没必要再找下去了
            return;
        }
        if(curIndex==len-1){
            if(curCount<maxK){
                maxK=curCount;
            }
        }
        while (curIndex<len-1){
            //若当前位置二者值不相同,那么我就需要去后面找当前A需要的char,进行交换
            if(arrA[curIndex]!=arrB[curIndex]){
                int pointer=curIndex+1;
                while (pointer<len){
                    if(arrB[pointer]==arrA[curIndex]){
                        swapChar(arrB,curIndex,pointer);
                        doSelect(arrA,arrB,len,curCount+1,curIndex+1);
                        swapChar(arrB,curIndex,pointer);//执行完本次交换回来,这样不影响其他
                    }
                    pointer++;
                }
                break;
            }else {
                curIndex++;
            }
        }
        if (curIndex == len-1){
            if (curCount < maxK) maxK = curCount;
        }
    }
    private void swapChar(char[] arrB,int i,int j){
        char temp=arrB[i];
        arrB[i]=arrB[j];
        arrB[j]=temp;
    }
}
原文地址:https://www.cnblogs.com/ningxinjie/p/13151779.html