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; } }