Leetcode 17.17 多次搜索 前缀树

  相比起暴力解法,前缀树可以实现空间换时间。将多个 small 构建为一棵前缀树,在树上遍历一次 big 。可替代用每个 small 与 big 比对。

  JAVA:

 private class Trie {
        boolean isEnd;
        Trie[] childs;
        int num;
        int flag;

        Trie() {
            this.num = 1;
            this.isEnd = false;
            this.childs = new Trie[26];
        }
    }

    public int[][] multiSearch(String big, String[] smalls) {
        Trie root = new Trie();
        int len = smalls.length, bigLen = big.length();
        for (int i = 0; i < len; i++) insert(root, smalls[i], i);
        List<List<Integer>> list = new ArrayList<List<Integer>>();
        for (int i = 0; i < len; i++) list.add(new LinkedList<Integer>());
        for (int i = 0; i < bigLen; i++) search(root, big.substring(i, bigLen), list, i);
        return toArray(list);
    }

    private final int[][] toArray(List<List<Integer>> list) {
        int len = list.size();
        int[][] reArr = new int[len][];
        for (int i = 0; i < len; i++) {
            List<Integer> inList = list.get(i);
            int inLen = inLen = inList.size();
            int[] inArr = new int[inLen];
            for (int j = 0; j < inLen; j++) {
                inArr[j] = inList.get(j);
            }
            reArr[i] = inArr;
        }
        return reArr;
    }

    private final void insert(Trie root, String str, int flag) {
        Trie node = root;
        for (int i = 0; i < str.length(); i++) {
            int point = str.charAt(i) - 'a';
            if (node.childs[point] == null) node.childs[point] = new Trie();
            else node.childs[point].num++;
            node = node.childs[point];
        }
        node.isEnd = true;
        node.flag = flag;
    }

    private final void search(Trie root, String str, List<List<Integer>> list, int flag) {
        Trie node = root;
        for (int i = 0; i < str.length(); i++) {
            int point = str.charAt(i) - 'a';
            if (node.childs[point] == null) return;
            if (node.childs[point].isEnd) {
                list.get(node.childs[point].flag).add(flag);
                System.out.println(node.childs[point].flag + " : " + flag);
            }
            node = node.childs[point];
        }
    }

  JS:

/**
 * @param {string} big
 * @param {string[]} smalls
 * @return {number[][]}
 */
var multiSearch = function (big, smalls) {
    let bigLen = big.length, smallLen = smalls.length, root = new Trie(), list = new Array(smallLen);
    for (let i = 0; i < smallLen; i++) {
        insert(root, smalls[i], i);
        list[i] = [];
    }
    for (let i = 0; i < bigLen; i++) search(root, big.substring(i, bigLen), list, i);
    return list;
};

var search = function (root, str, list, flag) {
    let node = root;
    for (let i = 0; i < str.length; i++) {
        let point = str.charAt(i).charCodeAt() - 97;
        if (!node.childs[point]) return;
        if (node.childs[point].isEnd) list[node.childs[point].flag].push(flag);
        node = node.childs[point];
    }
}

var insert = function (root, str, flag) {
    let node = root;
    for (let i = 0; i < str.length; i++) {
        let point = str.charAt(i).charCodeAt() - 97;
        if (!node.childs[point]) node.childs[point] = new Trie();
        else node.childs[point].num++;
        node = node.childs[point];
    }
    node.isEnd = true;
    node.flag = flag;
}

var Trie = function () {
    this.isEnd = false;
    this.childs = new Array(26);
    this.num = 1;
}

 

posted @ 2021-01-21 22:34  牛有肉  阅读(92)  评论(0编辑  收藏  举报