Skip to main content

Replace Question Marks in String to Minimize Its Value - Solution & Explanation

MediumHash TableStringGreedySorting17 min readAsked at: Amazon
Practice this problem

Problem Statement

You are given a string s. s[i] is either a lowercase English letter or '?'.

For a string t having length m containing only lowercase English letters, we define the function cost(i) for an index i as the number of characters equal to t[i] that appeared before it, i.e. in the range [0, i - 1].

The value of t is the sum of cost(i) for all indices i.

For example, for the string t = "aab":

  • cost(0) = 0
  • cost(1) = 1
  • cost(2) = 0
  • Hence, the value of "aab" is 0 + 1 + 0 = 1.

Your task is to replace all occurrences of '?' in s with any lowercase English letter so that the value of s is minimized.

Return a string denoting the modified string with replaced occurrences of '?'. If there are multiple strings resulting in the minimum value, return the lexicographically smallest one.

 

Example 1:

Input: s = "???"

Output: "abc"

Explanation: In this example, we can replace the occurrences of '?' to make s equal to "abc".

For "abc", cost(0) = 0, cost(1) = 0, and cost(2) = 0.

The value of "abc" is 0.

Some other modifications of s that have a value of 0 are "cba", "abz", and, "hey".

Among all of them, we choose the lexicographically smallest.

Example 2:

Input: s = "a?a?"

Output: "abac"

Explanation: In this example, the occurrences of '?' can be replaced to make s equal to "abac".

For "abac", cost(0) = 0, cost(1) = 0, cost(2) = 1, and cost(3) = 0.

The value of "abac" is 1.

 

Constraints:

  • 1 <= s.length <= 105
  • s[i] is either a lowercase English letter or '?'.

Approach Overview

Problem Overview: You are given a string containing lowercase letters and ?. Replace every ? with a lowercase character so the total value of the string is minimized. The value increases when the same character appears multiple times, so the goal is to distribute characters as evenly as possible while also returning the lexicographically smallest valid result.

Approach 1: Greedy with Min Heap / Set (Time: O(n log 26), Space: O(26))

This method treats the problem as a frequency balancing task. First count the frequency of existing characters using a small array or a hash table. Maintain a min-heap (or ordered set) of pairs (frequency, character). For every ?, extract the character with the smallest current frequency and assign it. After assignment, increment its frequency and push it back into the heap. This greedy rule works because adding the least-used character minimizes the incremental value cost. Once all replacements are chosen, sort the selected characters before placing them into the ? positions to ensure the lexicographically smallest result. The approach uses ideas from greedy algorithms and priority queues.

Approach 2: Optimized Greedy with Constant Space (Time: O(n), Space: O(1))

The heap is unnecessary because there are only 26 lowercase letters. Instead, maintain a fixed count[26] array using a counting technique. Scan the string once to compute current frequencies and count how many ? exist. For each replacement, linearly check the 26 letters and choose the one with the smallest frequency. Since the alphabet size is constant, this step is effectively O(1). Store the chosen characters, increment their counts, then sort this list before inserting them back into the original string. This produces the same balanced distribution as the heap approach but avoids the log factor and extra data structure.

Recommended for interviews: The greedy strategy is the key insight interviewers expect. Showing the heap-based solution demonstrates you understand how to repeatedly select the minimum-frequency character. The optimized constant-space version is typically preferred in a final solution because the alphabet size is fixed, reducing complexity to O(n) while keeping the implementation simple.

Approach 1: Greedy Approach with Set

This approach involves iterating through the string and replacing '?' with the smallest possible character that ensures the lexicographical order is upheld. We use a set to maintain previously seen characters to ensure minimal cost calculation.

This solution iterates through the string, using a set (an array of booleans) to track which characters are available to replace '?'. The replacement is done in a way that minimizes value and preserves lexical order.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time Complexity: O(n * 26), where n is the length of the string. Space Complexity: O(26) for storing character usage.

Try this approach in the editor →

Approach 2: Optimized Greedy Approach with Constant Space

This approach is an optimized variant of the greedy method. By minimizing the use of extra space, it modifies the string in place and maintains an array to track the last seen position of each character, leading to reduced cost and minimal space usage.

C implementation optimizes space by using an integer array to track the last seen position of characters. This helps avoid repetitive occurrence and ensures minimal cost.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time Complexity: O(n), Space Complexity: O(26) due to fixed alphabets tracking.

Try this approach in the editor →

Approach 3: Greedy + Priority Queue

According to the problem, we can find that if a letter c appears v times, then the score it contributes to the answer is 1 + 2 + cdots + (v - 1) = \frac{v times (v - 1)}{2}. To make the answer as small as possible, we should replace the question marks with those letters that appear less frequently.

Therefore, we can use a priority queue to maintain the occurrence times of each letter, take out the letter with the least occurrence times each time, record it in the array t, then increase its occurrence times by one, and put it back into the priority queue. Finally, we sort the array t, and then traverse the string s, replacing each question mark with the letters in the array t in turn.

The time complexity is O(n times log n), and the space complexity is O(n). Where n is the length of the string s.

Code

Python

Java

C++

Go

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Greedy Approach with Set

Time Complexity: O(n * 26), where n is the length of the string. Space Complexity: O(26) for storing character usage.

Optimized Greedy Approach with Constant Space

Time Complexity: O(n), Space Complexity: O(26) due to fixed alphabets tracking.

Greedy + Priority Queue—

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Greedy with Min Heap / SetO(n log 26)O(26)General greedy implementation when repeatedly selecting the least frequent character
Optimized Greedy with CountingO(n)O(1)Best approach when alphabet size is fixed (26 letters) and memory efficiency matters

Video Solution

3081. Replace Question Marks in String to Minimize Its Value | Priority Queue | Min Heap | Multiset • Aryan Mittal • 2,142 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Replace Question Marks in String to Minimize Its Value easy or hard?
Replace Question Marks in String to Minimize Its Value is generally classified as a Medium difficulty problem. The challenge comes from recognizing the greedy distribution principle and ensuring the lexicographically smallest valid string while minimizing duplicate character costs.
Replace Question Marks in String to Minimize Its Value Python/Java solution
Python and Java solutions typically implement the greedy strategy using either a PriorityQueue/min-heap or a simple frequency array. The algorithm counts existing characters, selects the least frequent letter for each '?', updates the count, and finally inserts the replacements in sorted order to maintain lexicographic minimality.
How to solve Replace Question Marks in String to Minimize Its Value in O(n)?
First count the frequency of each existing letter. For every '?' choose the character with the smallest frequency using a 26-length counting array. Store these chosen letters, update their counts, then sort the replacements before inserting them back into the string. Because the alphabet size is constant, each selection is O(1) and the overall complexity becomes O(n).
What is the best approach for Replace Question Marks in String to Minimize Its Value?
The most effective approach is a greedy frequency-balancing strategy. Track how many times each letter appears and always replace '?' with the character that currently has the smallest frequency. This minimizes the incremental value contributed by duplicates. With a fixed alphabet of 26 letters, the optimized counting approach runs in O(n) time and O(1) space.
Is Replace Question Marks in String to Minimize Its Value asked at Google/Amazon/Meta?
Greedy frequency balancing and string reconstruction problems like this frequently appear in interviews at companies such as Amazon, Google, and Meta. The exact problem may vary, but the pattern of distributing characters to minimize repetition and using a heap or counting array is common in coding interviews.
What data structure is used in Replace Question Marks in String to Minimize Its Value?
Common implementations use a frequency array combined with a min heap (priority queue). The heap helps repeatedly pick the character with the smallest current count. In optimized solutions, the heap can be replaced by a fixed-size counting array since there are only 26 lowercase letters.
What is the time complexity of Replace Question Marks in String to Minimize Its Value?
The optimal implementation runs in O(n) time where n is the length of the string. Each '?' replacement checks at most 26 characters, which is constant work. Space complexity is O(1) because only a fixed-size frequency array of length 26 is required.

Ready to solve this problem?

Practice Replace Question Marks in String to Minimize Its Value with our built-in code editor and test cases.

Practice on FleetCode