leetcode

Suffix Array (Non Leetcode)

assume you have a text - int[] text = {10, 20, 30, 25}

the suffix array will be:

suffix[0] = {10, 20, 30, 25}

suffix[1] = {20, 30, 25}

suffix[2] = {30, 25}

suffix[3] = {25}

if we sort them in lexical order, we get this suffix[0] < suffix[1] < suffix[3] < suffix[2]

Provide a method to get the sorted suffix index array. Follow up: if I want to search whether int[] sub = {20,30} is in the text, how to do it, suppose we already have the sorted suffix index array, do it in O(NlogN).

    public static class Suffix {
        public int[] suffixArray;
        public int index;
    }    

    public int[] constructSortedSuffixIndexArray(List<int[]> suffixArray) {
        Suffix[] array = new Suffix[suffixArray.size()];

        for (int i=0; i<array.length; i++) {
            Suffix s = new Suffix();
            s.index = i;
            s.suffixArray = suffixArray.get(i);
            array[i] = s;
        }


        int[] results = new int[suffixArray.size()];

        Comparator<Suffix> comp = new Comparator<Suffix>(){
            @Override 
            public int compare(Suffix s1, Suffix s2) {
                int[] a1 = s1.suffixArray;
                int[] a2 = s2.suffixArray;

                int i=0;
                int j=0;

                while(i<a1.length&&j<a2.length) {
                    if (a1[i]<a2[j]) {
                        return -1;
                    } else if (a1[i]>a2[j]) {
                        return 1;
                    }
                    i++;
                    j++;
                }

                if (i==a1.length&&j==a2.length) {
                    return 0;
                }

                if (i==a1.length) {
                    return -1;
                }

                if (j==a2.length) {
                    return 1;
                }
                return 0;
            }
        };

        Arrays.sort(array, comp);

        for (int i=0; i<results.length; i++) {
            results[i] = array[i].index;
        }

        return results;
    }

    //search particular pattern
    public boolean searchPattern(int[] pattern, List<int[]> suffixArray, int[] suffixOrderArray) {
        int left = 0;
        int right = suffixOrderArray.length-1;

        while (left<right) {
            int middle = left + (right-left)/2;
            int order = suffixOrderArray[middle];

            int comp = compareArray(pattern, suffixArray.get(order));

            if (comp==0) {
                return true;
            } else if (comp<0) {
                right = middle-1;
            } else {
                left = middle+1;
            }
        }

        return false;
     }

    public int compareArray(int[] sub, int[] suffix) {
        int i=0;
        int j=0;

        while(i<sub.length&&j<suffix.length) {
            if (sub[i]>suffix[j]) {
                return 1;
            } else if (sub[i]<suffix[j]){
                return -1;
            }
            i++;
            j++;
        }

        if (i==sub.length&&j==sub.length) {
            return 0;
        }

        return (i==sub.length) ? 0 : 1;

    }