AlgoMaster Logo

Minimum Cost to Convert String I

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

We need to convert one string into another, character by character. Each position is independent: the cost at position i depends only on converting source[i] to target[i]. The total cost is the sum of the individual character conversion costs.

Conversions can also be chained. There may be no direct rule from 'c' to 'b', but if 'c' can become 'e' for cost 1 and 'e' can become 'b' for cost 2, then 'c' can become 'b' for cost 3. Finding the cheapest such chain is a shortest path problem.

If we model each of the 26 lowercase letters as a node in a graph and each (original[i], changed[i], cost[i]) triplet as a directed edge, then finding the minimum cost to convert character x to character y is equivalent to finding the shortest path from node x to node y in this graph.

Key Constraints:

  • original[i], changed[i] are lowercase English letters → The graph has at most 26 nodes regardless of input size. That makes an O(V^3) all-pairs algorithm cost about 17,576 operations, which is a fixed constant.
  • 1 <= source.length <= 10^5 → The string can be long, so the per-position cost lookup must be O(1) after preprocessing the graph once.
  • 1 <= cost[i] <= 10^6 with up to 10^5 positions → A single path can sum many edges, and the total can reach roughly 10^5 × 26 × 10^6, well beyond a 32-bit integer. The accumulator and the distance matrix must use 64-bit integers.

Approach 1: Dijkstra from Each Source Character

Intuition

For each character that needs converting, the cheapest way to reach the target character is a single-source shortest path, which Dijkstra's algorithm computes.

Running Dijkstra once per string position would repeat work, since many positions share the same source character. There are only 26 possible source characters, so Dijkstra runs at most 26 times, once per starting letter, and the results cover every position. Each conversion then becomes a table lookup.

The plan: build a graph of 26 nodes (one per letter), run Dijkstra from each node, and store the shortest distance to every other node in a 26x26 table.

Algorithm

  1. Build an adjacency list for the 26-node character graph. For duplicate edges (same source and destination), keep only the minimum cost.
  2. Run Dijkstra's algorithm from each of the 26 characters to compute shortest paths to all other characters.
  3. Store results in a 26x26 distance matrix.
  4. Iterate through the string. For each position i:
    • If source[i] == target[i], add 0 to the total cost.
    • Otherwise, look up dist[source[i]][target[i]]. If it's infinity, return -1. Otherwise, add it to the total cost.
  5. Return the total cost.

Visualization and Code

Loading animation...

The Dijkstra approach runs the algorithm 26 times with separate per-source bookkeeping. The next approach computes all-pairs shortest paths with a single triple-nested loop over the 26 nodes.

Approach 2: Floyd-Warshall (Optimal)

Intuition

With only 26 nodes, Floyd-Warshall computes the shortest path between every pair of characters in a single triple-nested loop. For every pair of nodes (i, j), it checks whether routing through some intermediate node k is cheaper than the best path found so far.

The algorithm considers every node as a possible intermediate. After all 26 intermediates are processed, dist[i][j] holds the cheapest cost to convert character i into character j, whether directly or through a chain of conversions.

Floyd-Warshall fits this problem well: the graph is small, we need all-pairs distances rather than a single source, and the implementation is three nested loops over the 26 characters with no auxiliary data structures.

Algorithm

  1. Initialize a 26x26 distance matrix with infinity everywhere, except dist[i][i] = 0 for all i.
  2. For each conversion rule (original[i], changed[i], cost[i]), set dist[original[i]][changed[i]] to the minimum of its current value and cost[i] (handling duplicate edges).
  3. Run Floyd-Warshall: for each intermediate node k (0 to 25), for each pair (i, j), check if dist[i][k] + dist[k][j] < dist[i][j]. If so, update.
  4. Iterate through the string. For each position where source[i] != target[i], look up the shortest path cost. If any lookup returns infinity, return -1. Otherwise, sum up all costs.

Visualization and Code

Loading animation...