Input: words =["abc","aaaaa","bcdef"], target ="aabcdabc"Output: 3Explanation:
The target string can be formed by concatenating:* Prefix of length 2 of `words[1]`, i.e.`"aa"`.* Prefix of length 3 of `words[2]`, i.e.`"bcd"`.* Prefix of length 3 of `words[0]`, i.e.`"abc"`.
Input: words =["abababab","ab"], target ="ababaababa"Output: 2Explanation:
The target string can be formed by concatenating:* Prefix of length 5 of `words[0]`, i.e.`"ababa"`.* Prefix of length 5 of `words[0]`, i.e.`"ababa"`.
This is a classic word break problem, but with valid prefixes from the given words. We use a Trie for fast prefix lookup and DP to find the minimum splits.
import java.util.*;
classSolution {
publicintminValidStrings(String[] words, String target) {
Set<String> prefixes =new HashSet<>();
for (String w : words) {
for (int l = 1; l <= w.length(); l++)
prefixes.add(w.substring(0, l));
}
int n = target.length();
int[] dp =newint[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0]= 0;
for (int i = 1; i <= n; i++) {
for (int l = 1; l <= i; l++) {
if (prefixes.contains(target.substring(i - l, i))) {
dp[i]= Math.min(dp[i], dp[i - l]+ 1);
}
}
}
return dp[n]== Integer.MAX_VALUE?-1 : dp[n];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
funminValidStrings(words: Array<String>, target: String): Int {
val prefixes = mutableSetOf<String>()
for (w in words) for (l in1..w.length) prefixes.add(w.substring(0, l))
val n = target.length
val dp = IntArray(n + 1) { Int.MAX_VALUE }
dp[0] = 0for (i in1..n) {
for (l in1..i) {
if (prefixes.contains(target.substring(i - l, i))) {
dp[i] = minOf(dp[i], dp[i - l] + 1)
}
}
}
returnif (dp[n] ==Int.MAX_VALUE) -1else dp[n]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
classSolution:
defminValidStrings(self, words: list[str], target: str) -> int:
prefixes = set()
for w in words:
for l in range(1, len(w) +1):
prefixes.add(w[:l])
n = len(target)
dp = [float('inf')] * (n +1)
dp[0] =0for i in range(1, n +1):
for l in range(1, i +1):
if target[i - l:i] in prefixes:
dp[i] = min(dp[i], dp[i - l] +1)
return-1if dp[n] == float('inf') else dp[n]
use std::collections::HashSet;
impl Solution {
pubfnmin_valid_strings(words: Vec<String>, target: String) -> i32 {
letmut prefixes = HashSet::new();
for w in&words {
for l in1..=w.len() {
prefixes.insert(&w[..l]);
}
}
let n = target.len();
letmut dp =vec![i32::MAX; n +1];
dp[0] =0;
let t = target.as_bytes();
for i in1..=n {
for l in1..=i {
if prefixes.contains(std::str::from_utf8(&t[i - l..i]).unwrap()) {
dp[i] = dp[i].min(dp[i - l] +1);
}
}
}
if dp[n] ==i32::MAX { -1 } else { dp[n] }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
minValidStrings(words: string[], target: string):number {
constprefixes=newSet<string>();
for (constwofwords) for (letl=1; l<=w.length; ++l) prefixes.add(w.slice(0, l));
constn=target.length;
constdp= Array(n+1).fill(Infinity);
dp[0] =0;
for (leti=1; i<=n; ++i) {
for (letl=1; l<=i; ++l) {
if (prefixes.has(target.slice(i-l, i))) {
dp[i] = Math.min(dp[i], dp[i-l] +1);
}
}
}
returndp[n] ===Infinity?-1 : dp[n];
}
}