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; }
当你看清人们的真相,于是你知道了,你可以忍受孤独