Skip to content

Commit e8b5228

Browse files
committed
feat: add solutions to lc problem: No.1268
No.1268.Search Suggestions System
1 parent 01a7441 commit e8b5228

File tree

6 files changed

+305
-135
lines changed

6 files changed

+305
-135
lines changed

solution/1200-1299/1268.Search Suggestions System/README.md

Lines changed: 112 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@
6565

6666
**方法一:排序 + 前缀树**
6767

68+
题目要求在输入 `searchWord` 的每一个字母后,推荐 `products` 数组中前缀与 `searchWord` 相同的最多三个产品。如果前缀相同的可推荐产品超过三个,按字典序返回最小的三个。
69+
70+
找前缀相同的产品,可以使用前缀树;而要返回字典序最小的三个产品,我们可以先对 `products` 数组进行排序,然后将排序后的数组下标存入前缀树中。
71+
72+
前缀树的每个节点维护以下信息:
73+
74+
- `children`:这是一个长度为 $26$ 的数组,用于存储当前节点的子节点,`children[i]` 表示当前节点的子节点中字符为 `i + 'a'` 的节点。
75+
- `v`:这是一个数组,用于存储当前节点的子节点中的字符在 `products` 数组中的下标,最多存储三个下标。
76+
77+
搜索时,我们从前缀树的根节点开始,找到每一个前缀对应的下标数组,将其存入结果数组中。最后只需要将每个下标数组中的下标对应到 `products` 数组中即可。
78+
79+
时间复杂度 $O(L \times \log n + m)$,空间复杂度 $O(L)$。其中 $L$ 是 `products` 数组所有字符串的长度之和,而 $n$ 和 $m$ 分别是 `products` 数组的长度和 `searchWord` 的长度。
80+
6881
<!-- tabs:start -->
6982

7083
### **Python3**
@@ -74,28 +87,29 @@
7487
```python
7588
class Trie:
7689
def __init__(self):
77-
self.children = [None] * 26
78-
self.v = []
90+
self.children: List[Union[Trie, None]] = [None] * 26
91+
self.v: List[int] = []
7992

80-
def insert(self, word, i):
93+
def insert(self, w, i):
8194
node = self
82-
for c in word:
95+
for c in w:
8396
idx = ord(c) - ord('a')
8497
if node.children[idx] is None:
8598
node.children[idx] = Trie()
8699
node = node.children[idx]
87-
node.v.append(i)
100+
if len(node.v) < 3:
101+
node.v.append(i)
88102

89-
def search(self, word):
90-
res = [[] for _ in range(len(word))]
103+
def search(self, w):
91104
node = self
92-
for i, c in enumerate(word):
105+
ans = [[] for _ in range(len(w))]
106+
for i, c in enumerate(w):
93107
idx = ord(c) - ord('a')
94108
if node.children[idx] is None:
95109
break
96110
node = node.children[idx]
97-
res[i] = node.v[:3]
98-
return res
111+
ans[i] = node.v
112+
return ans
99113

100114

101115
class Solution:
@@ -106,8 +120,7 @@ class Solution:
106120
trie = Trie()
107121
for i, w in enumerate(products):
108122
trie.insert(w, i)
109-
res = trie.search(searchWord)
110-
return [[products[j] for j in v] for v in res]
123+
return [[products[i] for i in v] for v in trie.search(searchWord)]
111124
```
112125

113126
### **Java**
@@ -119,37 +132,34 @@ class Trie {
119132
Trie[] children = new Trie[26];
120133
List<Integer> v = new ArrayList<>();
121134

122-
void insert(String word, int i) {
135+
public void insert(String w, int i) {
123136
Trie node = this;
124-
for (char c : word.toCharArray()) {
125-
c -= 'a';
126-
if (node.children[c] == null) {
127-
node.children[c] = new Trie();
137+
for (int j = 0; j < w.length(); ++j) {
138+
int idx = w.charAt(j) - 'a';
139+
if (node.children[idx] == null) {
140+
node.children[idx] = new Trie();
128141
}
129-
node = node.children[c];
142+
node = node.children[idx];
130143
if (node.v.size() < 3) {
131144
node.v.add(i);
132145
}
133146
}
134147
}
135148

136-
List<List<Integer>> search(String word) {
137-
List<List<Integer>> res = new ArrayList<>();
138-
int n = word.length();
139-
for (int i = 0; i < n; ++i) {
140-
res.add(new ArrayList<>());
141-
}
149+
public List<Integer>[] search(String w) {
142150
Trie node = this;
151+
int n = w.length();
152+
List<Integer>[] ans = new List[n];
153+
Arrays.setAll(ans, k -> new ArrayList<>());
143154
for (int i = 0; i < n; ++i) {
144-
char c = word.charAt(i);
145-
c -= 'a';
146-
if (node.children[c] == null) {
155+
int idx = w.charAt(i) - 'a';
156+
if (node.children[idx] == null) {
147157
break;
148158
}
149-
node = node.children[c];
150-
res.set(i, node.v);
159+
node = node.children[idx];
160+
ans[i] = node.v;
151161
}
152-
return res;
162+
return ans;
153163
}
154164
}
155165

@@ -160,9 +170,8 @@ class Solution {
160170
for (int i = 0; i < products.length; ++i) {
161171
trie.insert(products[i], i);
162172
}
163-
List<List<Integer>> res = trie.search(searchWord);
164173
List<List<String>> ans = new ArrayList<>();
165-
for (List<Integer> v : res) {
174+
for (var v : trie.search(searchWord)) {
166175
List<String> t = new ArrayList<>();
167176
for (int i : v) {
168177
t.add(products[i]);
@@ -174,6 +183,66 @@ class Solution {
174183
}
175184
```
176185

186+
### **C++**
187+
188+
```cpp
189+
class Trie {
190+
public:
191+
void insert(string& w, int i) {
192+
Trie* node = this;
193+
for (int j = 0; j < w.size(); ++j) {
194+
int idx = w[j] - 'a';
195+
if (!node->children[idx]) {
196+
node->children[idx] = new Trie();
197+
}
198+
node = node->children[idx];
199+
if (node->v.size() < 3) {
200+
node->v.push_back(i);
201+
}
202+
}
203+
}
204+
205+
vector<vector<int>> search(string& w) {
206+
Trie* node = this;
207+
int n = w.size();
208+
vector<vector<int>> ans(n);
209+
for (int i = 0; i < w.size(); ++i) {
210+
int idx = w[i] - 'a';
211+
if (!node->children[idx]) {
212+
break;
213+
}
214+
node = node->children[idx];
215+
ans[i] = move(node->v);
216+
}
217+
return ans;
218+
}
219+
220+
private:
221+
vector<Trie*> children = vector<Trie*>(26);
222+
vector<int> v;
223+
};
224+
225+
class Solution {
226+
public:
227+
vector<vector<string>> suggestedProducts(vector<string>& products, string searchWord) {
228+
sort(products.begin(), products.end());
229+
Trie* trie = new Trie();
230+
for (int i = 0; i < products.size(); ++i) {
231+
trie->insert(products[i], i);
232+
}
233+
vector<vector<string>> ans;
234+
for (auto& v : trie->search(searchWord)) {
235+
vector<string> t;
236+
for (int i : v) {
237+
t.push_back(products[i]);
238+
}
239+
ans.push_back(move(t));
240+
}
241+
return ans;
242+
}
243+
};
244+
```
245+
177246
### **Go**
178247
179248
```go
@@ -185,9 +254,9 @@ type Trie struct {
185254
func newTrie() *Trie {
186255
return &Trie{}
187256
}
188-
func (this *Trie) insert(word string, i int) {
257+
func (this *Trie) insert(w string, i int) {
189258
node := this
190-
for _, c := range word {
259+
for _, c := range w {
191260
c -= 'a'
192261
if node.children[c] == nil {
193262
node.children[c] = newTrie()
@@ -199,37 +268,35 @@ func (this *Trie) insert(word string, i int) {
199268
}
200269
}
201270
202-
func (this *Trie) search(word string) [][]int {
271+
func (this *Trie) search(w string) [][]int {
203272
node := this
204-
n := len(word)
205-
res := make([][]int, n)
206-
for i, c := range word {
273+
n := len(w)
274+
ans := make([][]int, n)
275+
for i, c := range w {
207276
c -= 'a'
208277
if node.children[c] == nil {
209278
break
210279
}
211280
node = node.children[c]
212-
res[i] = node.v
281+
ans[i] = node.v
213282
}
214-
return res
283+
return ans
215284
}
216285
217-
func suggestedProducts(products []string, searchWord string) [][]string {
286+
func suggestedProducts(products []string, searchWord string) (ans [][]string) {
218287
sort.Strings(products)
219288
trie := newTrie()
220289
for i, w := range products {
221290
trie.insert(w, i)
222291
}
223-
res := trie.search(searchWord)
224-
var ans [][]string
225-
for _, v := range res {
292+
for _, v := range trie.search(searchWord) {
226293
t := []string{}
227294
for _, i := range v {
228295
t = append(t, products[i])
229296
}
230297
ans = append(ans, t)
231298
}
232-
return ans
299+
return
233300
}
234301
```
235302

0 commit comments

Comments
 (0)