@@ -47,7 +47,7 @@ mapSum.sum("ap"); // return 5 (apple + app = 3 + 2 = 5)
4747
4848* ` sum ` : 先对入参 $prefix$ 进行字典树搜索,到达尾部后再使用 ` DFS ` 搜索后面的所有方案,并累加结果。
4949
50- 代码:
50+ 代码( ` static ` 优化代码见 $P2,ドル避免每个样例都 ` new ` 大数组) :
5151``` Java
5252class MapSum {
5353 int [][] tr = new int [2510 ][26 ];
@@ -80,11 +80,126 @@ class MapSum {
8080 }
8181}
8282```
83+ 84+ 85+ ``` Java
86+ class MapSum {
87+ static int [][] tr = new int [2510 ][26 ];
88+ static int [] hash = new int [2510 ];
89+ static int idx;
90+ public MapSum () {
91+ for (int i = 0 ; i <= idx; i++ ) Arrays . fill(tr[i], 0 );
92+ Arrays . fill(hash, 0 );
93+ idx = 0 ;
94+ }
95+ public void insert (String key , int val ) {
96+ int p = 0 ;
97+ for (int i = 0 ; i < key. length(); i++ ) {
98+ int u = key. charAt(i) - ' a' ;
99+ if (tr[p][u] == 0 ) tr[p][u] = ++ idx;
100+ p = tr[p][u];
101+ }
102+ hash[p] = val;
103+ }
104+ public int sum (String prefix ) {
105+ int p = 0 ;
106+ for (int i = 0 ; i < prefix. length(); i++ ) {
107+ int u = prefix. charAt(i) - ' a' ;
108+ if (tr[p][u] == 0 ) return 0 ;
109+ p = tr[p][u];
110+ }
111+ return dfs(p);
112+ }
113+ int dfs (int p ) {
114+ int ans = hash[p];
115+ for (int u = 0 ; u < 26 ; u++ ) {
116+ if (tr[p][u] != 0 ) ans += dfs(tr[p][u]);
117+ }
118+ return ans;
119+ }
120+ }
121+ ```
83122* 时间复杂度:令 $key$ 的最大长度为 $n,ドル最大调用次数为 $m,ドル字符集大小为 $C$( 本题 $C$ 固定为 26ドル$ ),` insert ` 操作的复杂度为 $O(n)$;从 ` DFS ` 的角度分析,` sum ` 操作的复杂度为 $O(C^n),ドル但事实上,对于本题具有明确的计算量上界,搜索所有的格子的复杂度为 $O(n * m * C)$
84123* 空间复杂度:$O(n * m * C)$
85124
86125---
87126
127+ ### Trie 记录前缀字符串总和
128+ 129+ 为降低 ` sum ` 操作的复杂度,我们可以在 ` insert ` 操作中同时记录(累加)每个前缀的总和。
130+ 131+ 代码(` static ` 优化代码见 $P2,ドル避免每个样例都 ` new ` 大数组):
132+ ``` Java
133+ class MapSum {
134+ int N = 2510 ;
135+ int [][] tr = new int [N ][26 ];
136+ int [] hash = new int [N ];
137+ int idx;
138+ Map<String , Integer > map = new HashMap<> ();
139+ public void insert (String key , int val ) {
140+ int _val = val;
141+ if (map. containsKey(key)) val -= map. get(key);
142+ map. put(key, _val);
143+ for (int i = 0 , p = 0 ; i < key. length(); i++ ) {
144+ int u = key. charAt(i) - ' a' ;
145+ if (tr[p][u] == 0 ) tr[p][u] = ++ idx;
146+ p = tr[p][u];
147+ hash[p] += val;
148+ }
149+ }
150+ public int sum (String prefix ) {
151+ int p = 0 ;
152+ for (int i = 0 ; i < prefix. length(); i++ ) {
153+ int u = prefix. charAt(i) - ' a' ;
154+ if (tr[p][u] == 0 ) return 0 ;
155+ p = tr[p][u];
156+ }
157+ return hash[p];
158+ }
159+ }
160+ ```
161+ 162+ 163+ ``` Java
164+ class MapSum {
165+ static int N = 2510 ;
166+ static int [][] tr = new int [N ][26 ];
167+ static int [] hash = new int [N ];
168+ static int idx;
169+ static Map<String , Integer > map = new HashMap<> ();
170+ public MapSum () {
171+ for (int i = 0 ; i <= idx; i++ ) Arrays . fill(tr[i], 0 );
172+ Arrays . fill(hash, 0 );
173+ idx = 0 ;
174+ map. clear();
175+ }
176+ public void insert (String key , int val ) {
177+ int _val = val;
178+ if (map. containsKey(key)) val -= map. get(key);
179+ map. put(key, _val);
180+ for (int i = 0 , p = 0 ; i < key. length(); i++ ) {
181+ int u = key. charAt(i) - ' a' ;
182+ if (tr[p][u] == 0 ) tr[p][u] = ++ idx;
183+ p = tr[p][u];
184+ hash[p] += val;
185+ }
186+ }
187+ public int sum (String prefix ) {
188+ int p = 0 ;
189+ for (int i = 0 ; i < prefix. length(); i++ ) {
190+ int u = prefix. charAt(i) - ' a' ;
191+ if (tr[p][u] == 0 ) return 0 ;
192+ p = tr[p][u];
193+ }
194+ return hash[p];
195+ }
196+ }
197+ ```
198+ * 时间复杂度:令 $key$ 的最大长度为 $n,ドル` insert ` 操作的复杂度为 $O(n)$;` sum ` 操作的复杂度为 $O(n)$
199+ * 空间复杂度:令 $key$ 的最大长度为 $n,ドル最大调用次数为 $m,ドル字符集大小为 $C$( 本题 $C$ 固定为 26ドル$ ),复杂度为 $O(n * m * C)$
200+ 201+ ---
202+ 88203### 最后
89204
90205这是我们「刷穿 LeetCode」系列文章的第 ` No.677 ` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
0 commit comments