@@ -26,27 +26,126 @@ words = ["a", "bb", "acd", "ace"]
26
26
<li><code>words[i]</code>的长度在<code>[1, 50]</code>。</li>
27
27
</ul >
28
28
29
-
30
29
## 解法
31
30
32
31
<!-- 这里可写通用的实现逻辑 -->
33
32
33
+ 由于字符串 S 长度较大,如果暴力求解,会报超时错误,因此要避免对 S 的多次遍历。
34
+
35
+ 可以将所有单词根据首字母不同放入不同的 buckets 中,比如对于 ` words = ["a", "bb", "acd", "ace"] ` ,可以初始化 buckets 为如下形式:
36
+
37
+ ``` python
38
+ buckets = {
39
+ ' a' : [" a" , " acd" , " ace" ],
40
+ ' b' : [" bb" ],
41
+ }
42
+ ```
43
+
44
+ 然后遍历 S 中每个字符 c,在 buckets 中找到对应的 bucket 并取出所有元素 old。对于每个元素 t,如果长度为 1,说明 t 对应的单词已经遍历结束,该单词属于 S 的一个子序列,累加 res;否则将 t 取子串 ` t[1:] ` 放入 buckets 中。继续往下遍历 S,直至结束。
45
+
46
+ 最后返回 res 即可。
47
+
34
48
<!-- tabs:start -->
35
49
36
50
### ** Python3**
37
51
38
52
<!-- 这里可写当前语言的特殊实现逻辑 -->
39
53
40
54
``` python
41
-
55
+ class Solution :
56
+ def numMatchingSubseq (self , s : str , words : List[str ]) -> int :
57
+ buckets = collections.defaultdict(list )
58
+ for word in words:
59
+ buckets[word[0 ]].append(word)
60
+ res = 0
61
+ for c in s:
62
+ old = buckets[c][::1 ]
63
+ buckets[c].clear()
64
+ for t in old:
65
+ if len (t) == 1 :
66
+ res += 1
67
+ else :
68
+ buckets[t[1 ]].append(t[1 :])
69
+ return res
42
70
```
43
71
44
72
### ** Java**
45
73
46
74
<!-- 这里可写当前语言的特殊实现逻辑 -->
47
75
48
76
``` java
77
+ class Solution {
78
+ public int numMatchingSubseq (String s , String [] words ) {
79
+ List<String > [] buckets = new List [26 ];
80
+ for (int i = 0 ; i < buckets. length; ++ i) {
81
+ buckets[i] = new ArrayList<> ();
82
+ }
83
+ for (String word : words) {
84
+ buckets[word. charAt(0 ) - ' a' ]. add(word);
85
+ }
86
+ int res = 0 ;
87
+ for (char c : s. toCharArray()) {
88
+ List<String > old = new ArrayList<> (buckets[c - ' a' ]);
89
+ buckets[c - ' a' ]. clear();
90
+ for (String t : old) {
91
+ if (t. length() == 1 ) {
92
+ ++ res;
93
+ } else {
94
+ buckets[t. charAt(1 ) - ' a' ]. add(t. substring(1 ));
95
+ }
96
+ }
97
+ }
98
+ return res;
99
+ }
100
+ }
101
+ ```
102
+
103
+ ### ** C++**
104
+
105
+ ``` cpp
106
+ class Solution {
107
+ public:
108
+ int numMatchingSubseq(string s, vector<string >& words) {
109
+ vector<vector<string >> buckets(26);
110
+ for (auto word : words) buckets[ word[ 0] - 'a'] .push_back(word);
111
+ int res = 0;
112
+ for (auto c : s)
113
+ {
114
+ auto old = buckets[ c - 'a'] ;
115
+ buckets[ c - 'a'] .clear();
116
+ for (auto t : old)
117
+ {
118
+ if (t.size() == 1) ++res;
119
+ else buckets[ t[ 1] - 'a'] .push_back(t.substr(1));
120
+ }
121
+ }
122
+ return res;
123
+ }
124
+ };
125
+ ```
49
126
127
+ ### **Go**
128
+
129
+ ```go
130
+ func numMatchingSubseq(s string, words []string) int {
131
+ buckets := make([][]string, 26)
132
+ for _, word := range words {
133
+ buckets[word[0]-'a'] = append(buckets[word[0]-'a'], word)
134
+ }
135
+ res := 0
136
+ for _, c := range s {
137
+ old := buckets[c-'a']
138
+ buckets[c-'a'] = nil
139
+ for _, t := range old {
140
+ if len(t) == 1 {
141
+ res++
142
+ } else {
143
+ buckets[t[1]-'a'] = append(buckets[t[1]-'a'], t[1:])
144
+ }
145
+ }
146
+ }
147
+ return res
148
+ }
50
149
```
51
150
52
151
### ** ...**
0 commit comments