Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 711dd71

Browse files
Merge pull request SharingSource#416 from SharingSource/ac_oier
✨feat: Add 720 & Modify 211、432
2 parents 256f98e + d139a74 commit 711dd71

File tree

5 files changed

+156
-12
lines changed

5 files changed

+156
-12
lines changed

‎Index/字典树.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
| [212. 单词搜索 II](https://leetcode-cn.com/problems/word-search-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/word-search-ii/solution/gong-shui-san-xie-yi-ti-shuang-jie-hui-s-am8f/) | 困难 | 🤩🤩🤩🤩 |
66
| [421. 数组中两个数的最大异或值](https://leetcode-cn.com/problems/maximum-xor-of-two-numbers-in-an-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-xor-of-two-numbers-in-an-array/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-bmjdg/) | 中等 | 🤩🤩🤩🤩 |
77
| [677. 键值映射](https://leetcode-cn.com/problems/map-sum-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/map-sum-pairs/solution/gong-shui-san-xie-jie-he-dfs-de-trie-yun-i4xa/) | 中等 | 🤩🤩🤩🤩 |
8+
| [720. 词典中最长的单词](https://leetcode-cn.com/problems/longest-word-in-dictionary/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-word-in-dictionary/solution/by-ac_oier-bmot/) | 简单 | 🤩🤩🤩🤩 |
89
| [1707. 与数组中元素的最大异或值](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/solution/gong-shui-san-xie-jie-zhe-ge-wen-ti-lai-lypqr/) | 困难 | 🤩🤩🤩 |
910

‎Index/模拟.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
| [645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/set-mismatch/solution/gong-shui-san-xie-yi-ti-san-jie-ji-shu-s-vnr9/) | 简单 | 🤩🤩🤩 |
7373
| [709. 转换成小写字母](https://leetcode-cn.com/problems/to-lower-case/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/to-lower-case/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-czpo/) | 简单 | 🤩🤩🤩 |
7474
| [717. 1比特与2比特字符](https://leetcode-cn.com/problems/1-bit-and-2-bit-characters/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/1-bit-and-2-bit-characters/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-igh7/) | 简单 | 🤩🤩🤩 |
75+
| [720. 词典中最长的单词](https://leetcode-cn.com/problems/longest-word-in-dictionary/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-word-in-dictionary/solution/by-ac_oier-bmot/) | 简单 | 🤩🤩🤩🤩 |
7576
| [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-atoms/solution/gong-shui-san-xie-shi-yong-xiao-ji-qiao-l5ak4/) | 困难 | 🤩🤩🤩🤩 |
7677
| [747. 至少是其他数字两倍的最大数](https://leetcode-cn.com/problems/largest-number-at-least-twice-of-others/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/largest-number-at-least-twice-of-others/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-8179/) | 简单 | 🤩🤩🤩🤩🤩 |
7778
| [748. 最短补全词](https://leetcode-cn.com/problems/shortest-completing-word/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/shortest-completing-word/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-j-x4ao/) | 简单 | 🤩🤩🤩🤩 |

‎LeetCode/211-220/211. 添加与搜索单词 - 数据结构设计(中等).md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ Tag : 「DFS」、「字典树」
66

77
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
88

9-
实现词典类 WordDictionary :
10-
* WordDictionary() 初始化词典对象
11-
* void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
12-
* bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false
13-
* word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。
9+
实现词典类 `WordDictionary` :
10+
* `WordDictionary()` 初始化词典对象
11+
* `void addWord(word)``word` 添加到数据结构中,之后可以对它进行匹配
12+
* `bool search(word)` 如果数据结构中存在字符串与 `word` 匹配,则返回 `true` ;否则,返回 `false`
13+
* `word` 中可能包含一些 `'.'` ,每个 `.` 都可以表示任何一个字母。
1414

1515
示例:
1616
```
@@ -33,10 +33,10 @@ wordDictionary.search("b.."); // return True
3333
```
3434

3535
提示:
36-
* 1 <= word.length <= 500
37-
* addWord 中的 word 由小写英文字母组成
38-
* search 中的 word 由 '.' 或小写英文字母组成
39-
* 最多调用 50000 次 addWord 和 search
36+
* $1 <= word.length <= 500$
37+
* `addWord` 中的 `word` 由小写英文字母组成
38+
* `search` 中的 `word``'.'` 或小写英文字母组成
39+
* 最多调用 $50000$`addWord``search`
4040

4141
---
4242

@@ -110,7 +110,7 @@ class WordDictionary {
110110
}
111111
}
112112
```
113-
113+
114114
```Java
115115
class WordDictionary {
116116
int N = 250000;

‎LeetCode/431-440/432. 全 O(1) 的数据结构(困难).md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ allOne.getMinKey(); // 返回 "leet"
5353

5454
**我们可以采取和 [实现一个 LRUCache](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247486820&idx=1&sn=2055864e10848bce55afc4e2feda79a7&chksm=fd9ca67bcaeb2f6d2038706e32cafffd701d3d6b71b60c52a568ed6dc0e268d93f8a78498105&token=146288031&lang=zh_CN#rd) & [实现一个 LFUCache](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247486856&idx=1&sn=59b2ed57e4a75eac0e63fc0cf08bed5d&chksm=fd9ca697caeb2f81f83cdc741375f9130c3fa40463edb4ae98d702354ca106378fdfe23735ad&token=146288031&lang=zh_CN#rd) 类似的思路,通过自定义节点并手写双链表来实现。**
5555

56-
定义一个节点类 `Node`,除了包含用于实现双向链表的 `left``right` 以外,还包含一个数值类型的变量 `val`, 用于记录该节点存储的是计数次数为多少的元素,以及一个 `Set` 类型的容器,用于支持 $O(1)$ 插入和删除元素,记作 `set`
56+
定义一个节点类 `Node`,除了包含用于实现双向链表的 `left``right` 以外,还包含一个数值类型的变量 `cnt`, 用于记录该节点存储的是计数次数为多少的元素,以及一个 `Set` 类型的容器,用于支持 $O(1)$ 插入和删除元素,记作 `set`
5757

58-
同时为了快速知道某个字符串属于哪个 `Node`,我们还需要开一个「哈希表」进行定位(以字符串为哈希表的键,字符串所在 `Node` 作为值),当定位到字符串对应的 `Node` 之后则可以利用「双向链表」的 $O(1)$ 增加/修改/删除。
58+
同时为了快速知道某个字符串属于哪个 `Node`,我们还需要开一个「哈希表」进行定位(以字符串为哈希表的键,字符串所在 `Node` 作为值),当定位到字符串对应的 `Node` 之后则可以利用双向链表的 $O(1)$ 增加/修改/删除。
5959

6060
在双向链表中,起始只有两个哨兵节点 `hh``tt` ,当进行若干 `inc/dec` 操作后的基本形态为:
6161

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[720. 词典中最长的单词](https://leetcode-cn.com/problems/longest-word-in-dictionary/solution/by-ac_oier-bmot/)** ,难度为 **简单**
4+
5+
Tag : 「模拟」、「哈希表」、「字典树」
6+
7+
8+
9+
给出一个字符串数组 `words` 组成的一本英语词典。返回 `words` 中最长的一个单词,该单词是由 `words` 词典中其他单词逐步添加一个字母组成。
10+
11+
若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。
12+
13+
示例 1:
14+
```
15+
输入:words = ["w","wo","wor","worl", "world"]
16+
17+
输出:"world"
18+
19+
解释: 单词"world"可由"w", "wo", "wor", 和 "worl"逐步添加一个字母组成。
20+
```
21+
示例 2:
22+
```
23+
输入:words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
24+
25+
输出:"apple"
26+
27+
解释:"apply" 和 "apple" 都能由词典中的单词组成。但是 "apple" 的字典序小于 "apply"
28+
```
29+
30+
提示:
31+
* 1ドル <= words.length <= 1000$
32+
* 1ドル <= words[i].length <= 30$
33+
* 所有输入的字符串 $words[i]$ 都只包含小写字母。
34+
35+
---
36+
37+
### 模拟
38+
39+
数据范围很小,我们可以直接模拟来做。
40+
41+
先将所有的 $words[i]$ 存入 `Set` 集合,方便后续可以近似 $O(1)$ 查询某个子串是否存在 $words$ 中。
42+
43+
遍历 $words$ 数组(题目没有说 $words$ 不重复,因此最好遍历刚刚预处理的 `Set` 集合),判断每个 $words[i]$ 是否为「合法单词」,同时利用当前的最长单词来做剪枝。
44+
45+
不算剪枝效果,该做法计算量不超过 10ドル^6,ドル可以过。
46+
47+
代码:
48+
```Java
49+
class Solution {
50+
public String longestWord(String[] words) {
51+
String ans = "";
52+
Set<String> set = new HashSet<>();
53+
for (String s : words) set.add(s);
54+
for (String s : set) {
55+
int n = s.length(), m = ans.length();
56+
if (n < m) continue;
57+
if (n == m && s.compareTo(ans) > 0) continue;
58+
boolean ok = true;
59+
for (int i = 1; i <= n && ok; i++) {
60+
String sub = s.substring(0, i);
61+
if (!set.contains(sub)) ok = false;
62+
}
63+
if (ok) ans = s;
64+
}
65+
return ans;
66+
}
67+
}
68+
```
69+
* 时间复杂度:预处理 `Set` 集合复杂度近似 $O(n)$;判断某个 $words[i]$ 是否合法需要判断所有子串是否均在 $words$ 中,复杂度为 $O(m^2),ドル其中 $m$ 为字符串长度,处理 $words[i]$ 的过程还使用到 `compareTo` 操作,其复杂度为 $O(\min(N, M)),ドル其中 $N$ 和 $M$ 为参与比较的两字符串长度,该操作相比于生成子串可忽略,而对于一个长度为 $m$ 的字符串而言,生成其所有的子串的计算量为首项为 1ドル,ドル末项为 $m,ドル公差为 1ドル$ 的等差数列求和结果。整体复杂度为 $O(\sum_{i = 0}^{n - 1}words[i].length^2)$
70+
* 空间复杂度:$O(\sum_{i = 0}^{n - 1}words[i].length)$
71+
72+
---
73+
74+
### 字典树
75+
76+
上述解法中「枚举某个 $words[i]$ 的所有子串,并判断子串是否在 $words$ 数组中出现」的操作可使用「字典树」来实现。
77+
78+
**不了解「Trie / 字典树」的同学可以看前置 🧀:[字典树入门](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247488490&idx=1&sn=db2998cb0e5f08684ee1b6009b974089)。里面通过图例展示了字典树基本形态,以及提供了「数组实现」和「TrieNode 实现」两种方式,还有「数组大小估算方式」和「Trie 应用面」介绍。**
79+
80+
回到本题,起始先将所有的 $words[i]$ 存入字典树,并记录每个字符的结尾编号。
81+
82+
对于某个 $words[i]$ 而言,其能成为「合法单词」的充要条件为:$words[i]$ 的每个前缀编号都有「以结尾编号」所被记录。
83+
84+
> 一些细节:为了防止每个样例都 `new` 大数组,我们使用 `static` 进行优化,并在跑样例前进行相应的清理工作。
85+
86+
代码:
87+
```Java
88+
class Solution {
89+
static int N = 30010, M = 26;
90+
static int[][] tr = new int[N][M];
91+
static boolean[] isEnd = new boolean[N];
92+
static int idx = 0;
93+
void add(String s) {
94+
int p = 0, n = s.length();
95+
for (int i = 0; i < n; i++) {
96+
int u = s.charAt(i) - 'a';
97+
if (tr[p][u] == 0) tr[p][u] = ++idx;
98+
p = tr[p][u];
99+
}
100+
isEnd[p] = true;
101+
}
102+
boolean query(String s) {
103+
int p = 0, n = s.length();
104+
for (int i = 0; i < n; i++) {
105+
int u = s.charAt(i) - 'a';
106+
p = tr[p][u];
107+
if (!isEnd[p]) return false;
108+
}
109+
return true;
110+
}
111+
public String longestWord(String[] words) {
112+
Arrays.fill(isEnd, false);
113+
for (int i = 0; i <= idx; i++) Arrays.fill(tr[i], 0);
114+
idx = 0;
115+
116+
String ans = "";
117+
for (String s : words) add(s);
118+
for (String s : words) {
119+
int n = s.length(), m = ans.length();
120+
if (n < m) continue;
121+
if (n == m && s.compareTo(ans) > 0) continue;
122+
if (query(s)) ans = s;
123+
}
124+
return ans;
125+
}
126+
}
127+
```
128+
* 时间复杂度:将所有 $words[i]$ 存入字典树的复杂度为 $O(\sum_{i = 0}^{n - 1}words[i].length)$;查询每个 $words[i]$ 是否合法的复杂度为 $O(m),ドル其中 $m$ 为当前 $words[i]$ 长度。整体复杂度为 $O(\sum_{i = 0}^{n - 1}words[i].length)$
129+
* 空间复杂度:$O(C)$
130+
131+
---
132+
133+
### 最后
134+
135+
这是我们「刷穿 LeetCode」系列文章的第 `No.720` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
136+
137+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
138+
139+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
140+
141+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
142+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /