Pseudo-Isomorphic Substrings

Sort by

recency

|

18 Discussions

|

  • + 0 comments

    //Solution In Java

    import java.math.*;
    import java.util.*;
    
    public class S implements Runnable {
        static Random R = new Random(7777L);
        static int M = 100000, A = 26, H = BigInteger.probablePrime(17, R).intValue();
        static int[] P = new int[M * 2];
    
        static {
            P[0] = 1;
            for (int i = 1; i < P.length; i++) P[i] = P[i - 1] * H;
        }
    
        char[] s;
        int n;
        int[][] cm, cp, dh;
        int[] hp;
    
        void solve() throws IOException {
            s = new StringBuilder(in.readLine()).reverse().toString().toCharArray();
            n = s.length;
            cm = gcm(s);
            cp = gcp(cm);
            dh = gdh(s);
            hp = php(cp, dh);
    
            Integer[] sa = gsa();
            final int[] si = new int[n];
            for (int i = 0; i < n; i++) si[sa[i]] = i;
    
            NavigableSet<Integer> v = new TreeSet<>((p1, p2) -> si[p1] - si[p2]);
            long[] c = new long[n + 1];
    
            for (int p = n - 1; p >= 0; p--) {
                long is = 0;
                Integer np = v.lower(p);
                if (np != null) is = Math.max(is, lcp(p, np));
                np = v.higher(p);
                if (np != null) is = Math.max(is, lcp(p, np));
                c[p] = c[p + 1] + n - p - is;
                v.add(p);
            }
    
            for (int i = 0; i < n; i++) out.println(c[n - 1 - i]);
        }
    
        Integer[] gsa() {
            Integer[] sa = new Integer[n];
            for (int i = 0; i < n; i++) sa[i] = i;
            Arrays.sort(sa, (p1, p2) -> {
                if (p1.equals(p2)) return 0;
                int l = lcp(p1, p2);
                if (l == n - p1) return -1;
                if (l == n - p2) return 1;
                return cm[p1][s[p1 + l] - 'a'] - cm[p2][s[p2 + l] - 'a'];
            });
            return sa;
        }
    
        int lcp(int p1, int p2) {
            if (p1 > p2) return lcp(p2, p1);
            int rb = n - p2;
            int l = nl(p1, p2, Math.min(120, rb));
            int lb = 0;
            if (l == -1) {
                lb = Math.min(15, rb);
                while (lb <= rb) {
                    int m = (lb + rb) >> 1;
                    if (eq(p1, p2, m)) {
                        l = Math.max(l, m);
                        lb = m + 1;
                    } else rb = m - 1;
                }
            }
            return l;
        }
    
        int nl(int p1, int p2, int len) {
            int[] m1 = cm[p1], m2 = cm[p2];
            for (int i = 0; i < len; i++)
                if (m1[s[p1 + i] - 'a'] != m2[s[p2 + i] - 'a'])
                    return i;
            return -1;
        }
    
        boolean eq(int p1, int p2, int len) {
            if (p1 > p2) return eq(p2, p1, len);
            int h1 = h(p1, len);
            int h2 = h(p2, len);
            return P[p2 - p1] * h1 == h2;
        }
    
        int h(int p, int len) {
            int[] pr = cp[p];
            int[] hs = dh[p + len];
            int ha = -hp[p];
            for (int r = 0; r < pr.length; r++) ha += hs[pr[r]] * r;
            return ha;
        }
    
        static int[][] gcm(char[] s) {
            int n = s.length;
            int[][] ltn = gln(s);
            int[][] m = new int[n][A];
    
            for (int o = 0; o < n; o++) {
                int[] mp = m[o];
                Arrays.fill(mp, -1);
                int md = 0;
                mp[s[o] - 'a'] = md++;
                for (int pos = o; pos < n; ) {
                    int np = n;
                    int nc = -1;
                    for (int ch = 0; ch < A; ch++)
                        if (mp[ch] == -1)
                            if (np > ltn[pos][ch]) {
                                np = ltn[pos][ch];
                                nc = ch;
                            }
                    if (nc == -1) break;
                    mp[nc] = md++;
                    pos = np;
                }
            }
            return m;
        }
    
        static int[][] gln(char[] s) {
            int n = s.length;
            int[][] l = new int[n][A];
            for (int[] r : l) Arrays.fill(r, n);
            for (int i = n - 2; i >= 0; i--) {
                System.arraycopy(l[i + 1], 0, l[i], 0, A);
                l[i][s[i + 1] - 'a'] = i + 1;
            }
            return l;
        }
    
        static int[][] gdh(char[] s) {
            int n = s.length;
            int[][] d = new int[n + 1][A];
            for (int i = 0; i < n; i++) {
                System.arraycopy(d[i], 0, d[i + 1], 0, A);
                d[i + 1][s[i] - 'a'] += P[i];
            }
            return d;
        }
    
        static int[][] gcp(int[][] cm) {
            int n = cm.length;
            int[][] c = new int[n][];
            for (int p = 0; p < n; p++) c[p] = gc(cm[p]);
            return c;
        }
    
        static int[] gc(int[] m) {
            int[] p = new int[A];
            int la = 0;
            for (int ch = 0; ch < A; ch++)
                if (m[ch] != -1) {
                    p[m[ch]] = ch;
                    la = Math.max(la, m[ch]);
                }
            return Arrays.copyOf(p, la + 1);
        }
    
        static int[] php(int[][] cp, int[][] dh) {
            int n = cp.length;
            int[] h = new int[n];
            for (int p = 0; p < n; p++) {
                int[] hs = dh[p];
                int[] pr = cp[p];
                for (int r = 0; r < pr.length; r++) h[p] += hs[pr[r]] * r;
            }
            return h;
        }
    
        static S I = new S();
    
        public static void main(String[] a) {
            I.run();
        }
    
        public void run() {
            try {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
                solve();
                out.close();
            } catch (Throwable e) {
                e.printStackTrace();
                System.exit(999);
            }
        }
    
        BufferedReader in;
        PrintWriter out;
    }
    
  • + 0 comments

    I'm using C# and highest I could achieve right now is 53% pass test cases, all of the remaining testcase fails are either "abort called : Out of Memory" or runtime too long. I used Hash tables, and for the large input string it goes above 1 million hash size which is what I think makes it throw out of memory, any ideas how this can be avoided? should I redo and try a new approach? because on my local machine I can run the tests properly. I've tried optimizing as much as I can too.

  • + 1 comment
    def pseudoIsomorphicSubstrings(s):
        # Write your code here
        def cod(w):
            c, n, d = '', ord('a') - 1, {}
            for letter in w:
                if letter in d.keys():
                    c += d[letter]
                else:
                    n += 1
                    c += chr(n)
                    d[letter] = chr(n)
            return c
    
  • + 0 comments

    Here is my solution in java, python, C, C++, Csharp HackerRank Pseudo-Isomorphic Substrings

  • + 0 comments

    Here is the solution of Pseudo-Isomorphic Substrings Click Here