Apply Substitutions - Solution & Explanation
Problem Statement
You are given a replacements mapping and a text string that may contain placeholders formatted as %var%, where each var corresponds to a key in the replacements mapping. Each replacement value may itself contain one or more such placeholders. Each placeholder is replaced by the value associated with its corresponding replacement key.
Return the fully substituted text string which does not contain any placeholders.
Example 1:
Input: replacements = [["A","abc"],["B","def"]], text = "%A%_%B%"
Output: "abc_def"
Explanation:
- The mapping associates
"A"with"abc"and"B"with"def". - Replace
%A%with"abc"and%B%with"def"in the text. - The final text becomes
"abc_def".
Example 2:
Input: replacements = [["A","bce"],["B","ace"],["C","abc%B%"]], text = "%A%_%B%_%C%"
Output: "bce_ace_abcace"
Explanation:
- The mapping associates
"A"with"bce","B"with"ace", and"C"with"abc%B%". - Replace
%A%with"bce"and%B%with"ace"in the text. - Then, for
%C%, substitute%B%in"abc%B%"with"ace"to obtain"abcace". - The final text becomes
"bce_ace_abcace".
Constraints:
1 <= replacements.length <= 10- Each element of
replacementsis a two-element list[key, value], where:keyis a single uppercase English letter.valueis a non-empty string of at most 8 characters that may contain zero or more placeholders formatted as%<key>%.
- All replacement keys are unique.
- The
textstring is formed by concatenating all key placeholders (formatted as%<key>%) randomly from the replacements mapping, separated by underscores. text.length == 4 * replacements.length - 1- Every placeholder in the
textor in any replacement value corresponds to a key in thereplacementsmapping. - There are no cyclic dependencies between replacement keys.
Approach Overview
Problem Overview: You receive a set of substitution rules where a key maps to a string that may reference other keys. Applying substitutions requires expanding each key until only final characters remain. Dependencies between keys form a directed graph, so the main challenge is resolving them in the correct order while avoiding repeated work.
Approach 1: Hash Table + Recursion (DFS with Memoization) (Time: O(n + L), Space: O(n + L))
Store every substitution rule in a hash table so you can resolve a key in constant time. When expanding a key, recursively resolve every referenced token inside its string. This naturally forms a graph where nodes are variables and edges represent dependencies. A depth‑first traversal expands dependencies first, then builds the final resolved string for the current key.
Memoization prevents recomputing the same substitution multiple times. Once a key is fully expanded, cache the result in the hash map. Future lookups return instantly. This converts repeated expansions from exponential behavior into linear work relative to the total size of all strings.
Cycle detection is handled with a recursion stack or visiting set. If a key is encountered while it is still being processed, the rules contain a circular dependency. In most implementations you either reject the input or skip further expansion. Because each key is processed once and each character is appended once, the runtime stays O(n + L), where n is the number of rules and L is the total length of all expanded strings.
Approach 2: Graph + Topological Sort (Time: O(n + L), Space: O(n + L))
You can model the substitutions explicitly as a dependency graph and resolve them in topological order. First build adjacency lists showing which keys depend on which other keys. Then compute in‑degrees and run a BFS‑style topological sort. Keys with no dependencies resolve immediately because their substitution strings contain only literals.
As each node is processed, replace references in dependent nodes with the resolved value and reduce their in‑degree. Once a dependent node has no remaining unresolved references, it becomes eligible for processing. This approach avoids recursion and works well when the dependency graph is large or when iterative solutions are preferred.
Recommended for interviews: The Hash Table + DFS approach is typically expected. It is concise, naturally expresses dependency resolution, and shows familiarity with memoization and graph traversal. Mentioning the topological sort alternative demonstrates deeper understanding of dependency graphs and how DFS and BFS can both solve the same problem.
Solution
We use a hash table d to store the substitution mapping, and then define a function dfs to recursively replace the placeholders in the string.
The execution logic of the function dfs is as follows:
- Find the starting position
iof the first placeholder in the strings. If not found, returns; - Find the ending position
jof the first placeholder in the strings. If not found, returns; - Extract the key of the placeholder, and then recursively replace the value of the placeholder
d[key]; - Return the replaced string.
In the main function, we call the dfs function, pass in the text string text, and return the result.
The time complexity is O(m + n times L), and the space complexity is O(m + n times L). Where m is the length of the substitution mapping, and n and L are the length of the text string and the average length of the placeholders, respectively.
Code
Python
Java
C++
Go
TypeScript
Detailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Hash Table + DFS Recursion | O(n + L) | O(n + L) | General case. Clean recursive solution with memoization to resolve dependencies. |
| Graph + Topological Sort (BFS) | O(n + L) | O(n + L) | Useful when avoiding recursion or when explicitly modeling dependency graphs. |
Video Solution
leetcode 3481 Apply Substitutions | string replace method, Kahn's alg for topo sorting • Code-Yao • 1,401 views views
Watch 1 more video solutions →Frequently Asked Questions
Is Apply Substitutions easy or hard?
Apply Substitutions Python/Java solution
How to solve Apply Substitutions in O(n)?
What is the best approach for Apply Substitutions?
Is Apply Substitutions asked at Google/Amazon/Meta?
What data structure is used in Apply Substitutions?
What is the time complexity of Apply Substitutions?
Ready to solve this problem?
Practice Apply Substitutions with our built-in code editor and test cases.
Practice on FleetCode