1881. Maximum Value after Insertion
Problem Description
You are given a very large integer n
represented as a string and a single digit x
(where both the digits in n
and x
are between 1 and 9). The number n
can be either positive or negative.
Your task is to insert the digit x
anywhere within n
to create the maximum possible numerical value. The key constraint is that you cannot insert x
before the negative sign if n
is negative.
For positive numbers, you want to make the result as large as possible. For example:
- If
n = "73"
andx = 6
, inserting6
between7
and3
gives"763"
, which is the maximum possible value.
For negative numbers, you want to make the result as close to zero as possible (least negative). For example:
- If
n = "-55"
andx = 2
, inserting2
before the first5
gives"-255"
, which is greater than"-525"
or"-552"
.
The strategy differs based on the sign:
- For positive numbers: Insert
x
before the first digit that is smaller thanx
. This ensuresx
contributes its value at the highest possible position. - For negative numbers: Insert
x
before the first digit that is greater thanx
. This minimizes the absolute value of the negative number, making it closer to zero.
The function should return the resulting string after the optimal insertion of digit x
.
Intuition
To maximize a number, we need to understand how digit placement affects value. In positional notation, digits on the left have greater weight than digits on the right. For instance, in 763
, the 7
contributes 700
, while the 6
contributes 60
, and the 3
contributes 3
.
For positive numbers, we want the digit x
to be as far left as possible to maximize its contribution. However, we can't just place it at the beginning if there are already larger digits there. The key insight is: we should scan from left to right and insert x
right before the first digit that is smaller than x
. Why? Because:
- All digits to the left are greater than or equal to
x
, so placingx
any earlier would push a larger digit to the right, reducing the overall value - The first digit smaller than
x
is where we get the maximum benefit by havingx
take its position while pushing the smaller digit right
For negative numbers, the logic flips. To maximize a negative number means making it less negative (closer to zero). Here, we want smaller digits on the left to minimize the absolute value. So we scan from left to right (after the negative sign) and insert x
before the first digit that is greater than x
. This ensures:
- We keep all smaller or equal digits in their high-value positions
- We prevent larger digits from occupying higher positions by inserting
x
before them
The greedy approach works because once we find the optimal position, inserting x
anywhere else would either push a larger digit right (in positive numbers) or push a smaller digit right (in negative numbers), both of which would give us a suboptimal result.
Learn more about Greedy patterns.
Solution Approach
The implementation uses a greedy algorithm with a single pass through the string. Here's how the solution works:
-
Initialize a pointer: Start with
i = 0
to track the position where we'll insertx
. -
Handle negative numbers:
- Check if the first character is
"-"
. If it is, incrementi
to skip the negative sign (we can't insert before it). - Then iterate through the remaining digits using a while loop:
while i < len(n) and int(n[i]) <= x
- We continue moving right as long as the current digit is less than or equal to
x
- We stop when we find a digit greater than
x
or reach the end of the string - This ensures we insert
x
before the first digit that's greater than it, minimizing the absolute value
- Check if the first character is
-
Handle positive numbers:
- If there's no negative sign, iterate through digits:
while i < len(n) and int(n[i]) >= x
- We continue moving right as long as the current digit is greater than or equal to
x
- We stop when we find a digit less than
x
or reach the end of the string - This ensures we insert
x
before the first digit that's smaller than it, maximizing the value
- If there's no negative sign, iterate through digits:
-
Construct the result:
- Use string slicing to build the final result:
n[:i] + str(x) + n[i:]
n[:i]
gives us all characters before positioni
str(x)
converts the digit to a string for concatenationn[i:]
gives us all characters from positioni
to the end
- Use string slicing to build the final result:
The time complexity is O(n)
where n
is the length of the string, as we traverse the string once. The space complexity is O(n)
for creating the result string.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through two examples to illustrate the solution approach:
Example 1: Positive Number
- Input:
n = "462"
,x = 5
- Goal: Insert
5
to maximize the value
Step-by-step process:
- Initialize
i = 0
(starting position) - Check if negative:
n[0] = '4'
(not '-'), so it's positive - For positive numbers, find the first digit smaller than
x = 5
:- Position 0:
n[0] = '4'
, is4 >= 5
? No, so we stop here - We found that
4 < 5
, so insert before position 0
- Position 0:
- Construct result:
n[:0] + "5" + n[0:]
="" + "5" + "462"
="5462"
- Result:
"5462"
(maximized by placing 5 at the highest position)
Example 2: Negative Number
- Input:
n = "-132"
,x = 2
- Goal: Insert
2
to make the number as close to zero as possible (least negative)
Step-by-step process:
- Initialize
i = 0
(starting position) - Check if negative:
n[0] = '-'
, so it's negative - Skip the negative sign:
i = 1
- For negative numbers, find the first digit greater than
x = 2
:- Position 1:
n[1] = '1'
, is1 <= 2
? Yes, continue (i = 2
) - Position 2:
n[2] = '3'
, is3 <= 2
? No, so we stop here - We found that
3 > 2
, so insert before position 2
- Position 1:
- Construct result:
n[:2] + "2" + n[2:]
="-1" + "2" + "32"
="-1232"
- Result:
"-1232"
(which is greater than-1322
or-2132
, thus closer to zero)
The key insight: For positive numbers, we insert before the first smaller digit to maximize. For negative numbers, we insert before the first larger digit to minimize the absolute value.
Solution Implementation
1class Solution:
2 def maxValue(self, n: str, x: int) -> str:
3 """
4 Insert digit x into string n to create the maximum possible value.
5
6 Args:
7 n: A string representation of an integer (can be negative)
8 x: A single digit (0-9) to insert
9
10 Returns:
11 The string with x inserted at the optimal position for maximum value
12 """
13 # Initialize position pointer
14 position = 0
15
16 # Handle negative numbers differently
17 if n[0] == "-":
18 # Skip the negative sign
19 position += 1
20
21 # For negative numbers, we want to minimize the absolute value
22 # So we insert x before the first digit that is greater than x
23 while position < len(n) and int(n[position]) <= x:
24 position += 1
25 else:
26 # For positive numbers, we want to maximize the value
27 # So we insert x before the first digit that is less than x
28 while position < len(n) and int(n[position]) >= x:
29 position += 1
30
31 # Insert x at the calculated position
32 result = n[:position] + str(x) + n[position:]
33
34 return result
35
1class Solution {
2 /**
3 * Inserts digit x into string n to create the maximum possible value.
4 * For positive numbers, insert x before the first digit smaller than x.
5 * For negative numbers, insert x before the first digit larger than x.
6 *
7 * @param n The input number as a string (can be positive or negative)
8 * @param x The digit to insert (0-9)
9 * @return The maximum value string after inserting x
10 */
11 public String maxValue(String n, int x) {
12 int insertPosition = 0;
13
14 // Check if the number is negative
15 if (n.charAt(0) == '-') {
16 // For negative numbers, skip the negative sign
17 insertPosition++;
18
19 // Find the first digit that is greater than x
20 // Inserting before a larger digit minimizes the negative value's magnitude
21 while (insertPosition < n.length() && n.charAt(insertPosition) - '0' <= x) {
22 insertPosition++;
23 }
24 } else {
25 // For positive numbers, find the first digit that is smaller than x
26 // Inserting before a smaller digit maximizes the positive value
27 while (insertPosition < n.length() && n.charAt(insertPosition) - '0' >= x) {
28 insertPosition++;
29 }
30 }
31
32 // Build the result by concatenating:
33 // 1. The prefix (everything before the insertion point)
34 // 2. The digit x
35 // 3. The suffix (everything from the insertion point onwards)
36 return n.substring(0, insertPosition) + x + n.substring(insertPosition);
37 }
38}
39
1class Solution {
2public:
3 string maxValue(string n, int x) {
4 // Initialize index for traversing the string
5 int insertPosition = 0;
6
7 // Check if the number is negative
8 if (n[0] == '-') {
9 // For negative numbers, we want to minimize the absolute value
10 // Skip the negative sign
11 insertPosition++;
12
13 // Find the first digit that is greater than x
14 // Inserting x before a larger digit minimizes the absolute value
15 while (insertPosition < n.size() && n[insertPosition] - '0' <= x) {
16 insertPosition++;
17 }
18 } else {
19 // For positive numbers, we want to maximize the value
20 // Find the first digit that is smaller than x
21 // Inserting x before a smaller digit maximizes the value
22 while (insertPosition < n.size() && n[insertPosition] - '0' >= x) {
23 insertPosition++;
24 }
25 }
26
27 // Insert the digit x at the calculated position
28 // Convert x to character by adding '0'
29 n.insert(insertPosition, 1, x + '0');
30
31 return n;
32 }
33};
34
1/**
2 * Inserts digit x into string n to maximize the resulting value
3 * @param n - The input number as a string (can be negative)
4 * @param x - The digit to insert (0-9)
5 * @returns The maximum value string after inserting x
6 */
7function maxValue(n: string, x: number): string {
8 let insertPosition: number = 0;
9
10 // Handle negative numbers
11 if (n[0] === '-') {
12 // Start from position 1 (after the minus sign)
13 insertPosition = 1;
14
15 // For negative numbers, insert x before the first digit greater than x
16 // This minimizes the absolute value, thus maximizing the negative number
17 while (insertPosition < n.length && Number(n[insertPosition]) <= x) {
18 insertPosition++;
19 }
20 } else {
21 // For positive numbers, insert x before the first digit less than x
22 // This maximizes the positive number
23 while (insertPosition < n.length && Number(n[insertPosition]) >= x) {
24 insertPosition++;
25 }
26 }
27
28 // Construct the result by inserting x at the calculated position
29 const result: string = n.slice(0, insertPosition) + x.toString() + n.slice(insertPosition);
30 return result;
31}
32
Time and Space Complexity
The time complexity is O(m)
, where m
is the length of the string n
. The algorithm iterates through the string at most once using a while loop. In the worst case, it examines every character in the string before finding the insertion position, resulting in m
comparisons.
The space complexity is O(m)
for the output string. While the algorithm uses only a constant amount of extra variables (i
and the condition checks), the string concatenation operation n[:i] + str(x) + n[i:]
creates a new string of length m + 1
. In Python, string slicing and concatenation create new string objects rather than modifying in place, so the space required is proportional to the length of the input string.
Note: The reference answer states O(1)
space complexity, which would be accurate if we only consider auxiliary space (excluding the output). However, considering the space needed for the returned string, the total space complexity is O(m)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Comparison Logic for Negative Numbers
One of the most common mistakes is using the wrong comparison operator when handling negative numbers. Developers often mistakenly use the same logic for both positive and negative cases.
Incorrect Implementation:
if n[0] == "-":
position += 1
# WRONG: Using >= instead of <=
while position < len(n) and int(n[position]) >= x:
position += 1
Why it's wrong: For negative numbers, we want to minimize the absolute value. Using >=
would insert the digit too early, making the negative number larger in absolute value (more negative).
Example:
- Input:
n = "-132"
,x = 1
- Wrong logic would stop immediately at position 1 (since 1 >= 1), giving
"-1132"
- Correct logic continues until finding a digit > 1, giving
"-1132"
(same in this case, but considern = "-232"
,x = 1
) - With
n = "-232"
, wrong logic gives"-1232"
but correct gives"-1232"
(happens to be same) - Better example:
n = "-543"
,x = 6
- Wrong: stops at position 1, gives
"-6543"
- Correct: inserts at end, gives
"-5436"
(which is greater/closer to zero)
- Wrong: stops at position 1, gives
2. Forgetting to Convert x to String
Another common error is attempting to concatenate the integer x
directly with string slices.
Incorrect Implementation:
# WRONG: x is an integer, can't concatenate with strings result = n[:position] + x + n[position:] # TypeError!
Solution: Always convert x
to string before concatenation:
result = n[:position] + str(x) + n[position:]
3. Not Handling Edge Cases Properly
Edge Case 1: Single Character String
- Input:
n = "5"
,x = 8
- The algorithm should correctly insert at position 0 or 1
Edge Case 2: All Digits Are Equal
- Input:
n = "333"
,x = 3
- Should insert at the end for positive numbers (giving "3333")
- For negative
n = "-333"
,x = 3
, should also insert at the end (giving "-3333")
Edge Case 3: Empty Position After Loop
- When the loop reaches the end of the string, ensure the insertion still works correctly with string slicing
4. Misunderstanding the Goal for Negative Numbers
Developers sometimes think "maximum value" means making the negative number as negative as possible, but the goal is actually to make it as close to zero as possible (least negative).
Wrong Understanding:
- Thinking
-555
is "larger" than-255
because 555 > 255
Correct Understanding:
-255
>-555
on the number line (closer to zero)- We want to minimize the absolute value for negative numbers
Which of the following array represent a max heap?
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Donβt Miss This!