Skip to content

Commit 2618f2d

Browse files
authoredDec 17, 2024
feat: add solutions to lc problem: No.3292 (#3866)
No.3292.Minimum Number of Valid Strings to Form Target II
1 parent 8070bfc commit 2618f2d

File tree

6 files changed

+795
-8
lines changed

6 files changed

+795
-8
lines changed
 

‎solution/3200-3299/3292.Minimum Number of Valid Strings to Form Target II/README.md

+265-4
Original file line numberDiff line numberDiff line change
@@ -102,25 +102,286 @@ tags:
102102
#### Python3
103103

104104
```python
105-
105+
class Hashing:
106+
__slots__ = ["mod", "h", "p"]
107+
108+
def __init__(self, s: List[str], base: int, mod: int):
109+
self.mod = mod
110+
self.h = [0] * (len(s) + 1)
111+
self.p = [1] * (len(s) + 1)
112+
for i in range(1, len(s) + 1):
113+
self.h[i] = (self.h[i - 1] * base + ord(s[i - 1])) % mod
114+
self.p[i] = (self.p[i - 1] * base) % mod
115+
116+
def query(self, l: int, r: int) -> int:
117+
return (self.h[r] - self.h[l - 1] * self.p[r - l + 1]) % self.mod
118+
119+
120+
class Solution:
121+
def minValidStrings(self, words: List[str], target: str) -> int:
122+
def f(i: int) -> int:
123+
l, r = 0, min(n - i, m)
124+
while l < r:
125+
mid = (l + r + 1) >> 1
126+
sub = hashing.query(i + 1, i + mid)
127+
if sub in s[mid]:
128+
l = mid
129+
else:
130+
r = mid - 1
131+
return l
132+
133+
base, mod = 13331, 998244353
134+
hashing = Hashing(target, base, mod)
135+
m = max(len(w) for w in words)
136+
s = [set() for _ in range(m + 1)]
137+
for w in words:
138+
h = 0
139+
for j, c in enumerate(w, 1):
140+
h = (h * base + ord(c)) % mod
141+
s[j].add(h)
142+
ans = last = mx = 0
143+
n = len(target)
144+
for i in range(n):
145+
dist = f(i)
146+
mx = max(mx, i + dist)
147+
if i == last:
148+
if i == mx:
149+
return -1
150+
last = mx
151+
ans += 1
152+
return ans
106153
```
107154

108155
#### Java
109156

110157
```java
111-
158+
class Hashing {
159+
private final long[] p;
160+
private final long[] h;
161+
private final long mod;
162+
163+
public Hashing(String word, long base, int mod) {
164+
int n = word.length();
165+
p = new long[n + 1];
166+
h = new long[n + 1];
167+
p[0] = 1;
168+
this.mod = mod;
169+
for (int i = 1; i <= n; i++) {
170+
p[i] = p[i - 1] * base % mod;
171+
h[i] = (h[i - 1] * base + word.charAt(i - 1)) % mod;
172+
}
173+
}
174+
175+
public long query(int l, int r) {
176+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
177+
}
178+
}
179+
180+
class Solution {
181+
private Hashing hashing;
182+
private Set<Long>[] s;
183+
184+
public int minValidStrings(String[] words, String target) {
185+
int base = 13331, mod = 998244353;
186+
hashing = new Hashing(target, base, mod);
187+
int m = Arrays.stream(words).mapToInt(String::length).max().orElse(0);
188+
s = new Set[m + 1];
189+
Arrays.setAll(s, k -> new HashSet<>());
190+
for (String w : words) {
191+
long h = 0;
192+
for (int j = 0; j < w.length(); j++) {
193+
h = (h * base + w.charAt(j)) % mod;
194+
s[j + 1].add(h);
195+
}
196+
}
197+
198+
int ans = 0;
199+
int last = 0;
200+
int mx = 0;
201+
int n = target.length();
202+
for (int i = 0; i < n; i++) {
203+
int dist = f(i, n, m);
204+
mx = Math.max(mx, i + dist);
205+
if (i == last) {
206+
if (i == mx) {
207+
return -1;
208+
}
209+
last = mx;
210+
ans++;
211+
}
212+
}
213+
return ans;
214+
}
215+
216+
private int f(int i, int n, int m) {
217+
int l = 0, r = Math.min(n - i, m);
218+
while (l < r) {
219+
int mid = (l + r + 1) >> 1;
220+
long sub = hashing.query(i + 1, i + mid);
221+
if (s[mid].contains(sub)) {
222+
l = mid;
223+
} else {
224+
r = mid - 1;
225+
}
226+
}
227+
return l;
228+
}
229+
}
112230
```
113231

114232
#### C++
115233

116234
```cpp
117-
235+
class Hashing {
236+
private:
237+
vector<long long> p;
238+
vector<long long> h;
239+
long long mod;
240+
241+
public:
242+
Hashing(const string& word, long long base, int mod) {
243+
int n = word.size();
244+
p.resize(n + 1);
245+
h.resize(n + 1);
246+
p[0] = 1;
247+
this->mod = mod;
248+
for (int i = 1; i <= n; i++) {
249+
p[i] = (p[i - 1] * base) % mod;
250+
h[i] = (h[i - 1] * base + word[i - 1]) % mod;
251+
}
252+
}
253+
254+
long long query(int l, int r) {
255+
return (h[r] - h[l - 1] * p[r - l + 1] % mod + mod) % mod;
256+
}
257+
};
258+
259+
class Solution {
260+
public:
261+
int minValidStrings(vector<string>& words, string target) {
262+
int base = 13331, mod = 998244353;
263+
Hashing hashing(target, base, mod);
264+
int m = 0, n = target.size();
265+
for (const string& word : words) {
266+
m = max(m, (int) word.size());
267+
}
268+
269+
vector<unordered_set<long long>> s(m + 1);
270+
for (const string& w : words) {
271+
long long h = 0;
272+
for (int j = 0; j < w.size(); j++) {
273+
h = (h * base + w[j]) % mod;
274+
s[j + 1].insert(h);
275+
}
276+
}
277+
278+
auto f = [&](int i) -> int {
279+
int l = 0, r = min(n - i, m);
280+
while (l < r) {
281+
int mid = (l + r + 1) >> 1;
282+
long long sub = hashing.query(i + 1, i + mid);
283+
if (s[mid].count(sub)) {
284+
l = mid;
285+
} else {
286+
r = mid - 1;
287+
}
288+
}
289+
return l;
290+
};
291+
292+
int ans = 0, last = 0, mx = 0;
293+
for (int i = 0; i < n; i++) {
294+
int dist = f(i);
295+
mx = max(mx, i + dist);
296+
if (i == last) {
297+
if (i == mx) {
298+
return -1;
299+
}
300+
last = mx;
301+
ans++;
302+
}
303+
}
304+
return ans;
305+
}
306+
};
118307
```
119308

120309
#### Go
121310

122311
```go
123-
312+
type Hashing struct {
313+
p []int64
314+
h []int64
315+
mod int64
316+
}
317+
318+
func NewHashing(word string, base int64, mod int64) *Hashing {
319+
n := len(word)
320+
p := make([]int64, n+1)
321+
h := make([]int64, n+1)
322+
p[0] = 1
323+
for i := 1; i <= n; i++ {
324+
p[i] = (p[i-1] * base) % mod
325+
h[i] = (h[i-1]*base + int64(word[i-1])) % mod
326+
}
327+
return &Hashing{p, h, mod}
328+
}
329+
330+
func (hashing *Hashing) Query(l, r int) int64 {
331+
return (hashing.h[r] - hashing.h[l-1]*hashing.p[r-l+1]%hashing.mod + hashing.mod) % hashing.mod
332+
}
333+
334+
func minValidStrings(words []string, target string) (ans int) {
335+
base, mod := int64(13331), int64(998244353)
336+
hashing := NewHashing(target, base, mod)
337+
338+
m, n := 0, len(target)
339+
for _, w := range words {
340+
m = max(m, len(w))
341+
}
342+
343+
s := make([]map[int64]bool, m+1)
344+
345+
f := func(i int) int {
346+
l, r := 0, int(math.Min(float64(n-i), float64(m)))
347+
for l < r {
348+
mid := (l + r + 1) >> 1
349+
sub := hashing.Query(i+1, i+mid)
350+
if s[mid][sub] {
351+
l = mid
352+
} else {
353+
r = mid - 1
354+
}
355+
}
356+
return l
357+
}
358+
359+
for _, w := range words {
360+
h := int64(0)
361+
for j := 0; j < len(w); j++ {
362+
h = (h*base + int64(w[j])) % mod
363+
if s[j+1] == nil {
364+
s[j+1] = make(map[int64]bool)
365+
}
366+
s[j+1][h] = true
367+
}
368+
}
369+
370+
var last, mx int
371+
372+
for i := 0; i < n; i++ {
373+
dist := f(i)
374+
mx = max(mx, i+dist)
375+
if i == last {
376+
if i == mx {
377+
return -1
378+
}
379+
last = mx
380+
ans++
381+
}
382+
}
383+
return ans
384+
}
124385
```
125386

126387
<!-- tabs:end -->

0 commit comments

Comments
 (0)