Implement templated string replacement
Company: Crowdstrike
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates proficiency in string parsing and template substitution, efficient use of dictionaries for key lookups, and the ability to reason about algorithmic time and space complexity.
Part 1: Replace Placeholders in a Single Template String
Constraints
- 0 <= len(template) <= 100000
- 0 <= len(values) <= 100000
- Every placeholder in `template` is well-formed as `{{key}}`
- Every placeholder key appearing in `template` exists in `values`
- Keys contain only letters, digits, and underscores
Examples
Input: ({"db_host": "example.com", "db_port": 5001}, "application is now connecting to {{db_host}}:{{db_port}}")
Expected Output: "application is now connecting to example.com:5001"
Explanation: Both placeholders are replaced with their mapped values.
Input: ({}, "plain text only")
Expected Output: "plain text only"
Explanation: Edge case: the template contains no placeholders, so it is returned unchanged.
Input: ({"count": 0}, "{{count}}")
Expected Output: "0"
Explanation: A single placeholder fills the entire string, and the numeric value is converted to text.
Input: ({"a": "X", "b": 7}, "{{a}}{{b}}-{{a}}")
Expected Output: "X7-X"
Explanation: This checks adjacent placeholders and repeated use of the same key.
Input: ({"name": "Ada"}, "")
Expected Output: ""
Explanation: Edge case: an empty template should return an empty string.
Solution
def solution(values, template):
result = []
i = 0
n = len(template)
while i < n:
if i + 1 < n and template[i] == '{' and template[i + 1] == '{':
j = i + 2
while j + 1 < n and not (template[j] == '}' and template[j + 1] == '}'):
j += 1
key = template[i + 2:j]
result.append(str(values[key]))
i = j + 2
else:
result.append(template[i])
i += 1
return ''.join(result)Time complexity: O(n + r), where n is the length of `template` and r is the total length of inserted replacement text. Space complexity: O(n + r) for the output being built.
Hints
- Scan the template from left to right. When you see `{{`, keep moving until you find the matching `}}` to extract the key.
- Build the answer using a list of string pieces and join at the end, instead of repeatedly concatenating strings.
Part 2: Replace Placeholders Across a Dictionary of Template Strings
Constraints
- 0 <= len(templates) <= 100000
- Let L be the total length of all strings in `templates`; L can be up to 200000
- Let K be the number of distinct keys in `values`
- Every placeholder in every template is well-formed as `{{key}}`
- Every placeholder key appearing in any template exists in `values`
- Keys contain only letters, digits, and underscores
Examples
Input: ({"db_host": "example.com", "db_port": 5001}, {"conn_msg": "application is now connecting to {{db_host}}:{{db_port}}", "short_msg": "{{db_host}}:{{db_port}}"})
Expected Output: {"conn_msg": "application is now connecting to example.com:5001", "short_msg": "example.com:5001"}
Explanation: Both template strings are rendered using the same `values` dictionary.
Input: ({"db_host": "example.com"}, {})
Expected Output: {}
Explanation: Edge case: if there are no templates, the result is an empty dictionary.
Input: ({"host": "srv", "port": 8080}, {"empty": "", "literal": "ready", "pair": "{{host}}:{{port}}"})
Expected Output: {"empty": "", "literal": "ready", "pair": "srv:8080"}
Explanation: This checks an empty template string, a template with no placeholders, and a normal replacement.
Input: ({"x": "A", "y": "B"}, {"combo": "{{x}}{{y}}{{x}}", "bracket": "[{{y}}]"})
Expected Output: {"combo": "ABA", "bracket": "[B]"}
Explanation: This checks adjacent placeholders and repeated use of the same key across multiple templates.
Input: ({"host": "local", "port": 0}, {"msg": "{{host}}:{{port}}"})
Expected Output: {"msg": "local:0"}
Explanation: Boundary-style case: a numeric value of 0 should still be converted and inserted correctly.
Solution
def solution(values, templates):
rendered_values = {key: str(value) for key, value in values.items()}
def render(template):
result = []
i = 0
n = len(template)
while i < n:
if i + 1 < n and template[i] == '{' and template[i + 1] == '{':
j = i + 2
while j + 1 < n and not (template[j] == '}' and template[j + 1] == '}'):
j += 1
key = template[i + 2:j]
result.append(rendered_values[key])
i = j + 2
else:
result.append(template[i])
i += 1
return ''.join(result)
return {name: render(template) for name, template in templates.items()}Time complexity: O(L + K) average, where L is the total length of all template strings and K is the number of keys in `values`. Space complexity: O(K + L_out), where `L_out` is the total length of the rendered output strings.
Hints
- Solve one template string at a time using the same parsing idea as in the single-template version.
- If some values are integers, convert each `values[key]` to a string once before processing all templates.