LeetCode Contest 248

最后一题不会做,使用RabinKarp的Hash匹配算法

T1: Build Array from Permutation

暴力模拟

T2: Eliminate Maximum Number of Monsters

计算到达的时间,排序,然后模拟统计

T3: Count Good Numbers

数论方法,直接计算即可

T4: Longest Common Subpath

使用RaBinKarp的算法计算,详细见代码(Java数学处理没Python优势):

class Solution {
    private Set<Long> RabinKarp(int[] path, int len, long mod) {
        Set<Long> allHashes = new HashSet<>();

        long h = 1;
        long h2 = 2;
        long n = 17 * len -17;
        while(n>0) {
            if (n % 2==1) {
                h = (h * h2) % mod;
            }
            h2 = (h2 * h2)% mod;
            n=n >> 1;
        }

        long t = 0;
        long d = 1 << 17;

        for(int i=0;i<len;i++) {
            t = (d * t + path[i]) % mod;
        }
        allHashes.add(t);
        for(int i=0;i<path.length-len;i++) {
            t = (t - path[i] * h) % mod;
            t = (d * t + path[i+len]) % mod;
            t = (t+mod)%mod;
            allHashes.add(t);
        }

        return allHashes;
    }

    public int longestCommonSubpath(int n, int[][] paths) {
        int m = paths.length;
        int[] u = new int[]{1, 19, 61, 69, 85, 99, 105};
        int uk = u.length;
        long[] mods = new long[uk];
        for(int i=0;i<uk;i++) {
            mods[i] = (1 << 31) - u[i];
        }
        int st=0;
        int en=paths[0].length+1;
        for(int i=1;i<m;i++){
            en = Math.min(en, paths[i].length+1);
        }
        while (st+1<en) {
            int mid = (st + en)>>1;
            boolean globalCheck = true;
            for(int i=0;i<uk;i++) {
                Set<Long> value = RabinKarp(paths[0], mid, mods[i]);
                for(int k=0;k<m;k++) {
                    if (value.isEmpty()) {
                        break;
                    }
                    Set<Long> temp = RabinKarp(paths[k], mid, mods[i]);
                    value.retainAll(temp);
                }
                if (value.isEmpty()) {
                    globalCheck = false;
                    break;
                }
            }
            System.out.println(st+":"+en+":"+mid+":"+globalCheck);
            if (globalCheck) {
                st = mid;
            } else {
                en = mid;
            }
        }
        return st;
    }
}