KMP 并查集

73 阅读1分钟

1.KMP

/*
* str1:主串
* str2:模式串
* next[i]:i之前最长相等前后缀长度
* */
public static int getIndexOf(String str1,String str2){
    if(str2.length()>str1.length() || str1.length()==0 || str2.length()==0) return -1;
    char[] m = str1.toCharArray();
    char[] n = str2.toCharArray();
    int[] next = new int[n.length];
    next = getNext(n,next);
    int i = 0;
    int j = 0;
    while (i<m.length && j<n.length){
        if(m[i]==n[j]){
            i++;
            j++;
        }else {      // 如果不相等
            if(next[j]==-1) i++;
            else {
                j = next[j];
            }
        }
    }
    return j==n.length?i-j:-1;
}

public static int[] getNext(char[] n,int[] next){
    next[0] = -1;
    if(n.length==1) return next;
    next[1] = 0;
    if(n.length==2) return next;
    int i = 2;      //i表示当前下标
    int help = 0;   //help表示前缀后一个位置的坐标
    while (i<n.length){
        //help一开始指向next[i-1]位置
        if(n[i-1]==n[help]){
            next[i++] = ++help;
        }else {
            //如果不相等,help往前跳,每次跳到next[help]的位置
            //跳到最前面都不相等
            if(help==0){
                next[i++] = 0;
            }
            //不相等help往前跳
            else {
                help = next[help];
            }
        }
    }
    return next;
}

2.并查集

  功能:
 (1)将用户传来的每个元素都包装成一个集合
 (2)提供一个查询方法isSameSet(),查询两个元素是否属于一个集合
 (3)提供一个union()方法,将两个元素合并成一个集合
 
public class UnionFind<T> {


    public static class Element<T>{
        T value;

        public Element(T value) {
            this.value = value;
        }
    }
    /*
    * elementMap:用于查询元素是否加进过并查集
    * fatherMap:记录某个元素的直接父节点
    * sizeMap:记录某一个集合的大小,每个集合只有一条记录
    * */
    public HashMap<T,Element<T>> elementMap;
    public HashMap<Element<T>,Element<T>> fatherMap;
    public HashMap<Element<T>,Integer> sizeMap;

    public UnionFind(List<T> list) {
        for (T value : list) {
            Element<T> element = new Element<>(value);
            elementMap.put(value,element);
            fatherMap.put(element,element);
            sizeMap.put(element,1);
        }
    }


    public Element<T> findHead(Element<T> element){
        PriorityQueue<Element<T>> queue = new PriorityQueue<>();
        while (element!=fatherMap.get(element)){
            queue.add(element);
            element = fatherMap.get(element);
        }
        while (!queue.isEmpty()){
            fatherMap.put(queue.poll(),element);
        }
        return element;
    }


    public boolean isSameSet(T a,T b){
        if(elementMap.containsKey(a) && elementMap.containsKey(b)){
            Element<T> aF = findHead(elementMap.get(a));
            Element<T> bF = findHead(elementMap.get(b));
            if(aF==bF) return true;
        }
        return false;
    }


    public void Union(T a,T b){
        if(!elementMap.containsKey(a) || !elementMap.containsKey(b) || isSameSet(a,b)) return;
        Element<T> aF = findHead(elementMap.get(a));
        Element<T> bF = findHead(elementMap.get(b));
        Element<T> max = sizeMap.get(aF)>sizeMap.get(bF)?aF:bF;
        Element<T> min = max==aF?bF:aF;
        fatherMap.put(min,max);
        sizeMap.put(max,sizeMap.get(max)+sizeMap.get(min));
        sizeMap.remove(min);
    }
}