2976. Minimum Cost to Convert String I (Floyd-Warshall)¶
Edited by Charles
Medium · Python · Graph
Problem
Read the original problem on LeetCode.
The official page contains the problem statement, examples, and constraints.
Explanation, examples & other approaches
Core idea
The key observation is that each lowercase English letter can be considered a node in a directed weighted graph.
Original study notes follow, including intermediate snippets and earlier attempts.
Problem¶
You are given two strings source and target of the same length.
You are also given three arrays:
where:
represents a valid character conversion with cost:
A character may be converted multiple times through intermediate characters.
For example:
Then:
can be achieved with total cost:
The goal is to convert source into target with the minimum total cost.
If the conversion is impossible, return -1.
Approach: Floyd-Warshall¶
The key observation is that each lowercase English letter can be considered a node in a directed weighted graph.
There are only:
so the graph contains exactly 26 nodes:
A conversion rule:
is a directed edge whose weight is:
Therefore, the problem becomes:
Find the minimum conversion cost between every pair of letters.
This is an All-Pairs Shortest Path problem, so Floyd-Warshall is a natural solution.
Define dp¶
Create a 26 × 26 matrix:
where:
represents:
The minimum cost to convert letter
iinto letterj.
For example:
dp[0][1] = minimum cost from 'a' to 'b'
dp[0][2] = minimum cost from 'a' to 'c'
dp[1][3] = minimum cost from 'b' to 'd'
The size is 26 × 26 because the nodes of the graph are characters, not positions in source and target.
Initialize the Diagonal¶
Converting a character into itself costs nothing.
Therefore:
So:
All other conversions are initially impossible:
Convert Characters to Array Indices¶
We need to map:
We can use Python's ord() function:
For example:
ord('a') - ord('a') = 97 - 97 = 0
ord('b') - ord('a') = 98 - 97 = 1
ord('c') - ord('a') = 99 - 97 = 2
Therefore:
converts the characters into valid indices of dp.
Add the Direct Conversion Rules¶
For every conversion:
with cost:
we update:
We need min() because there may be multiple rules between the same two characters.
For example:
We should keep:
rather than simply using whichever rule appears last.
Floyd-Warshall¶
Now run Floyd-Warshall:
for k in range(26):
for i in range(26):
for j in range(26):
dp[i][j] = min(
dp[i][j],
dp[i][k] + dp[k][j]
)
The meaning of the transition is:
Current best:
i --------> j
dp[i][j]
Try going through k:
i --------> k --------> j
dp[i][k] dp[k][j]
Therefore:
In other words:
Check whether using
kas an intermediate character makes the conversion fromitojcheaper.
Example of Floyd-Warshall¶
Suppose the conversion rules are:
Initially:
When Floyd considers b as an intermediate character:
the cost is:
Since:
we update:
So Floyd automatically finds cheaper conversions involving multiple intermediate characters.
Convert source to target¶
After Floyd-Warshall finishes:
contains the minimum cost to convert any character u into any character v.
Now iterate through source and target position by position:
Convert both characters into indices:
Then the minimum conversion cost for this position is simply:
Add it to the result:
Impossible Conversion¶
If:
then there is no sequence of conversion rules that can transform:
Therefore the entire string conversion is impossible:
Otherwise, add the minimum cost to the answer.
Why Can We Calculate Each Position Independently?¶
Each operation changes one character.
Changing the character at one position does not affect characters at other positions.
Therefore:
can be solved independently.
The final answer is simply:
Overall Process¶
original / changed / cost
↓
Build a graph of 26 characters
↓
Initialize dp[26][26]
↓
Add direct conversion costs
↓
Run Floyd-Warshall
↓
Find minimum cost between every pair of characters
↓
Traverse source and target
↓
For each position:
source[i] -> target[i]
↓
Look up dp[u][v]
↙ ↘
inf finite
↓ ↓
return -1 add to res
↓
return res
Why Floyd-Warshall?¶
There are only 26 possible lowercase letters.
Floyd-Warshall takes:
Here:
so:
which is extremely small.
After Floyd-Warshall, every character conversion can be answered in:
time.
Complexity¶
Let:
Building the Graph¶
We process every conversion rule once:
Floyd-Warshall¶
There are 26 nodes:
Processing the Strings¶
We traverse source and target once:
Therefore the total time complexity is:
Since 26³ is a constant, this is effectively:
Space Complexity¶
The Floyd matrix is:
Therefore:
which is effectively:
Key Takeaways¶
Graph Modeling¶
Floyd-Warshall¶
Transition:
Character Mapping¶
maps:
Overall Idea¶
Study record
| Field | Value |
|---|---|
| Attempts | 1 |
| Mastery | ❚ |
| The Latest Attempt | September 3, 2026 |
Python solution¶
class Solution:
def minimumCost(
self,
source: str,
target: str,
original: List[str],
changed: List[str],
cost: List[int]
) -> int:
dp = [[float('inf')] * 26 for _ in range(26)]
for i in range(26):
dp[i][i] = 0
for org, cgd, c in zip(original, changed, cost):
u = ord(org) - ord('a')
v = ord(cgd) - ord('a')
dp[u][v] = min(dp[u][v], c)
# Floyd-Warshall
for k in range(26):
for i in range(26):
for j in range(26):
dp[i][j] = min(
dp[i][k] + dp[k][j],
dp[i][j]
)
res = 0
for charS, charT in zip(source, target):
u = ord(charS) - ord('a')
v = ord(charT) - ord('a')
if dp[u][v] == float('inf'):
return -1
res += dp[u][v]
return res