題目地址:
https://leetcode.com/problems/index-pairs-of-a-string/
給定一個字符串,再給定一個字符串數組,如果數組中一個字符串是的子串,那麼就記下該子串在中的起始和結尾的下標(包括起始字符和結尾字符的下標)。返回所有這樣的下標。
思路是用Trie。先將數組中所有字符串存入一個Trie,然後從的每一個位置開始,在Trie中搜索是否存在的前綴,如果存在,則返回所有前綴的結尾下標。
import java.util.ArrayList;
import java.util.List;
public class Solution {
class Trie {
class Node {
boolean isWord;
Node[] next;
Node() {
next = new Node[26];
}
}
private Node root;
Trie(String[] words) {
root = new Node();
for (String word : words) {
insert(word);
}
}
private void insert(String word) {
Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next[c - 'a'] == null) {
cur.next[c - 'a'] = new Node();
}
cur = cur.next[c - 'a'];
}
cur.isWord = true;
}
// 在Trie裏查找所有word[start:]的前綴,並把前綴的結尾字符的下標返回
public List<Integer> hasPrefix(String word, int start) {
List<Integer> end = new ArrayList<>();
Node cur = root;
for (int i = start; i < word.length(); i++) {
char c = word.charAt(i);
// 走到null的時候說明更長的前綴不可能再有了,退出循環
if (cur.next[c - 'a'] == null) {
break;
}
cur = cur.next[c - 'a'];
// 找到一個前綴,就將其結尾下標加入list
if (cur.isWord) {
end.add(i);
}
}
return end;
}
}
public int[][] indexPairs(String text, String[] words) {
List<int[]> list = new ArrayList<>();
Trie trie = new Trie(words);
// 查找text[i:]在trie裏存在的所有前綴,並把區間端點加入list
for (int i = 0; i < text.length(); i++) {
for (int end : trie.hasPrefix(text, i)) {
list.add(new int[]{i, end});
}
}
// 轉爲數組返回
int[][] res = new int[list.size()][];
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
return res;
}
}
時間複雜度,爲text長度,爲words字符串個數,爲words裏最長字符串的長度。空間複雜度。