@@ -103,11 +103,12 @@ tags:
103
103
``` python
104
104
class Solution :
105
105
def getWordsInLongestSubsequence (
106
- self , n : int , words : List[str ], groups : List[int ]
106
+ self , words : List[str ], groups : List[int ]
107
107
) -> List[str ]:
108
108
def check (s : str , t : str ) -> bool :
109
109
return len (s) == len (t) and sum (a != b for a, b in zip (s, t)) == 1
110
110
111
+ n = len (groups)
111
112
f = [1 ] * n
112
113
g = [- 1 ] * n
113
114
mx = 1
@@ -132,7 +133,8 @@ class Solution:
132
133
133
134
``` java
134
135
class Solution {
135
- public List<String > getWordsInLongestSubsequence (int n , String [] words , int [] groups ) {
136
+ public List<String > getWordsInLongestSubsequence (String [] words , int [] groups ) {
137
+ int n = groups. length;
136
138
int [] f = new int [n];
137
139
int [] g = new int [n];
138
140
Arrays . fill(f, 1 );
@@ -180,7 +182,7 @@ class Solution {
180
182
``` cpp
181
183
class Solution {
182
184
public:
183
- vector<string > getWordsInLongestSubsequence(int n, vector<string >& words, vector<int >& groups) {
185
+ vector<string > getWordsInLongestSubsequence(vector<string >& words, vector<int >& groups) {
184
186
auto check = [ ] (string& s, string& t) {
185
187
if (s.size() != t.size()) {
186
188
return false;
@@ -191,6 +193,7 @@ public:
191
193
}
192
194
return cnt == 1;
193
195
};
196
+ int n = groups.size();
194
197
vector<int > f(n, 1);
195
198
vector<int > g(n, -1);
196
199
int mx = 1;
@@ -221,7 +224,7 @@ public:
221
224
#### Go
222
225
223
226
```go
224
- func getWordsInLongestSubsequence(n int, words []string, groups []int) []string {
227
+ func getWordsInLongestSubsequence(words []string, groups []int) []string {
225
228
check := func(s, t string) bool {
226
229
if len(s) != len(t) {
227
230
return false
@@ -234,6 +237,7 @@ func getWordsInLongestSubsequence(n int, words []string, groups []int) []string
234
237
}
235
238
return cnt == 1
236
239
}
240
+ n := len(groups)
237
241
f := make([]int, n)
238
242
g := make([]int, n)
239
243
for i := range f {
@@ -261,17 +265,16 @@ func getWordsInLongestSubsequence(n int, words []string, groups []int) []string
261
265
break
262
266
}
263
267
}
264
- for i, j := 0, len(ans)-1; i < j; i, j = i+1, j-1 {
265
- ans[i], ans[j] = ans[j], ans[i]
266
- }
268
+ slices.Reverse(ans)
267
269
return ans
268
270
}
269
271
```
270
272
271
273
#### TypeScript
272
274
273
275
``` ts
274
- function getWordsInLongestSubsequence(n : number , words : string [], groups : number []): string [] {
276
+ function getWordsInLongestSubsequence(words : string [], groups : number []): string [] {
277
+ const n = groups .length ;
275
278
const f: number [] = Array (n ).fill (1 );
276
279
const g: number [] = Array (n ).fill (- 1 );
277
280
let mx = 1 ;
@@ -313,16 +316,12 @@ function getWordsInLongestSubsequence(n: number, words: string[], groups: number
313
316
314
317
``` rust
315
318
impl Solution {
316
- pub fn get_words_in_longest_subsequence (
317
- n : i32 ,
318
- words : Vec <String >,
319
- groups : Vec <i32 >,
320
- ) -> Vec <String > {
319
+ pub fn get_words_in_longest_subsequence (words : Vec <String >, groups : Vec <i32 >) -> Vec <String > {
321
320
fn check (s : & str , t : & str ) -> bool {
322
321
s . len () == t . len () && s . chars (). zip (t . chars ()). filter (| (a , b )| a != b ). count () == 1
323
322
}
324
323
325
- let n = n as usize ;
324
+ let n = groups . len () ;
326
325
327
326
let mut f = vec! [1 ; n ];
328
327
let mut g = vec! [- 1 ; n ];
@@ -364,66 +363,4 @@ impl Solution {
364
363
365
364
<!-- solution: end -->
366
365
367
- <!-- solution: start -->
368
-
369
- ### 方法二:动态规划 + 通配符哈希表
370
-
371
- 在方法一中,我们需要枚举所有的 $i$ 和 $j$ 组合, 这一步可以通过维护一个通配符哈希表来优化. 对于每个字符串 $word[ i] $, 我们枚举它的每个字符, 将其替换为通配符, 然后将替换后的字符串作为键, 将其下标作为值存入哈希表中. 这样我们可以在 $O(L)$ 时间内找到所有距离 $word[ i] $ 汉明距离为 1 的 $word[ j] $. 尽管时间复杂度仍然是 $O(n^2 \times L)$, 但平均复杂度会有所降低.
372
-
373
- <!-- tabs: start -->
374
-
375
- #### Java
376
-
377
- ``` java
378
- class Solution {
379
- public List<String > getWordsInLongestSubsequence (int n , String [] words , int [] groups ) {
380
- int [] dp = new int [n];
381
- int [] next = new int [n];
382
- Map<String , List<Integer > > strToIdxMap = new HashMap<> ();
383
- int maxIdx = n;
384
- for (int i = n - 1 ; i >= 0 ; i-- ) {
385
- int prevIdx = n;
386
- char [] word = words[i]. toCharArray();
387
- for (int j = 0 ; j < word. length; j++ ) {
388
- // convert word to pattern with '*'.
389
- char temp = word[j];
390
- word[j] = ' *' ;
391
- String curr = new String (word);
392
-
393
- // search matches and update dp.
394
- List<Integer > prevList = strToIdxMap. getOrDefault(curr, List . of());
395
- for (int prev : prevList) {
396
- if (groups[prev] == groups[i] || dp[prev] < dp[i]) {
397
- continue ;
398
- }
399
- dp[i] = dp[prev] + 1 ;
400
- prevIdx = prev;
401
- }
402
-
403
- // append current pattern to dictionary.
404
- strToIdxMap. computeIfAbsent(curr, k - > new ArrayList<> ()). add(i);
405
-
406
- // restore pattern to orignal word.
407
- word[j] = temp;
408
- }
409
- if (maxIdx >= n || dp[i] > dp[maxIdx]) {
410
- maxIdx = i;
411
- }
412
- next[i] = prevIdx;
413
- }
414
- int curr = maxIdx;
415
- List<String > ans = new ArrayList<> ();
416
- while (curr < n) {
417
- ans. add(words[curr]);
418
- curr = next[curr];
419
- }
420
- return ans;
421
- }
422
- }
423
- ```
424
-
425
- <!-- tabs: end -->
426
-
427
- <!-- solution: end -->
428
-
429
366
<!-- problem: end -->
0 commit comments