Input: target ="abcdef", words =["abdef","abc","d","def","ef"], costs =[100,1,1,10,5]Output: 7Explanation:
The minimum cost can be achieved by performing the following operations:* Select index 1 and append `"abc"` to `s` at a cost of 1, resulting in`s = "abc"`.* Select index 2 and append `"d"` to `s` at a cost of 1, resulting in`s = "abcd"`.* Select index 4 and append `"ef"` to `s` at a cost of 5, resulting in`s = "abcdef"`.
Example 2:
1
2
3
4
Input: target ="aaaa", words =["z","zz","zzz"], costs =[1,10,100]Output: -1Explanation:
It is impossible to make `s` equal to `target`, so we return-1.
Constraints:
1 <= target.length <= 2000
1 <= words.length == costs.length <= 50
1 <= words[i].length <= target.length
target and words[i] consist only of lowercase English letters.
We want to build the target string by appending words from the list, minimizing the total cost. Since the constraints are small, we can use a simple DP where for each position, we check all words that could end at that position and update the minimum cost.
classSolution {
publicintminimumCost(String target, String[] words, int[] costs) {
int n = target.length();
int[] dp =newint[n+1];
Arrays.fill(dp, (int)1e9);
dp[0]= 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < words.length; j++) {
int m = words[j].length();
if (i >= m && target.substring(i-m, i).equals(words[j])) {
dp[i]= Math.min(dp[i], dp[i-m]+ costs[j]);
}
}
}
return dp[n]>= 1e9 ?-1 : dp[n];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funminimumCost(target: String, words: Array<String>, costs: IntArray): Int {
val n = target.length
val dp = IntArray(n+1) { 1_000_000_000 }
dp[0] = 0for (i in1..n) {
for (j in words.indices) {
val m = words[j].length
if (i >= m && target.substring(i-m, i) == words[j]) {
dp[i] = minOf(dp[i], dp[i-m] + costs[j])
}
}
}
returnif (dp[n] >=1_000_000_000) -1else dp[n]
}
}
1
2
3
4
5
6
7
8
9
10
11
classSolution:
defminimumCost(self, target: str, words: list[str], costs: list[int]) -> int:
n = len(target)
dp = [float('inf')] * (n+1)
dp[0] =0for i in range(1, n+1):
for w, c in zip(words, costs):
m = len(w)
if i >= m and target[i-m:i] == w:
dp[i] = min(dp[i], dp[i-m] + c)
return-1if dp[n] == float('inf') else dp[n]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
impl Solution {
pubfnminimum_cost(target: String, words: Vec<String>, costs: Vec<i32>) -> i32 {
let n = target.len();
let t = target.as_bytes();
letmut dp =vec![i32::MAX; n+1];
dp[0] =0;
for i in1..=n {
for (w, &c) in words.iter().zip(costs.iter()) {
let m = w.len();
if i >= m &&&t[i-m..i] == w.as_bytes() {
dp[i] = dp[i].min(dp[i-m] + c);
}
}
}
if dp[n] ==i32::MAX { -1 } else { dp[n] }
}
}
⏰ Time complexity: O(n * W * L), where n is the length of target, W is the number of words, and L is the average word length. For each position, we check all words.