1802. Maximum Value at a Given Index in a Bounded Array
Problem Description
You need to construct an array of length n where the element at position index is maximized, while satisfying several constraints.
Given three positive integers:
n: the length of the array to constructindex: the position where you want to maximize the value (0-indexed)maxSum: the maximum allowed sum of all array elements
The constructed array nums must satisfy:
- Length constraint: The array must have exactly
nelements - Positive values: All elements must be positive integers (at least 1)
- Adjacent difference constraint: The absolute difference between any two adjacent elements must be at most 1. In other words,
|nums[i] - nums[i+1]| ≤ 1for all validi - Sum constraint: The sum of all elements cannot exceed
maxSum - Optimization goal: The value at
nums[index]should be as large as possible
The problem asks you to return the maximum possible value of nums[index].
For example, if you place a large value at nums[index], the adjacent difference constraint forces nearby elements to also be relatively large (they can only decrease by 1 at each step). This creates a "hill" shape in the array centered at index. The challenge is to find the highest possible peak value at index while ensuring the total sum doesn't exceed maxSum.
The optimal strategy is to make nums[index] as large as possible, then have values decrease by 1 as you move away from index in both directions, until reaching 1. Any remaining positions would be filled with 1s to minimize the sum.
Intuition
The key insight is recognizing that to maximize nums[index], we should minimize the sum of all other elements while respecting the constraints. Since adjacent elements can differ by at most 1, and all values must be positive (at least 1), the optimal array structure forms a "peak" or "hill" centered at index.
Starting from nums[index] = x, the values should decrease by 1 as we move away from index in both directions until reaching 1, then remain at 1 for any remaining positions. This gives us the minimum possible sum for a given peak value x.
For example, if index = 3, n = 7, and nums[index] = 5, the optimal array would look like: [2, 3, 4, 5, 4, 3, 2]. If the array is longer and values reach 1 before the ends, we'd have something like: [1, 1, 3, 4, 5, 4, 3, 2, 1].
Now comes the crucial observation: as we increase the value at nums[index], the total sum of the array increases monotonically. This monotonic property makes binary search the perfect tool to find the maximum valid value.
We can binary search on the value of nums[index]. For each candidate value mid, we calculate the minimum possible array sum with nums[index] = mid. If this sum is within maxSum, we know we can potentially go higher, so we search in the upper half. If the sum exceeds maxSum, we need to search for a smaller value.
To efficiently calculate the array sum for a given peak value, we split it into two parts:
- Left side: elements from position 0 to
index - 1 - Right side: elements from position
indexton - 1
Each side forms an arithmetic sequence decreasing by 1 until reaching 1, which allows us to use the arithmetic sequence sum formula for quick calculation. This transforms our problem into a binary search with O(1) validation at each step.
Learn more about Greedy, Math and Binary Search patterns.
Solution Implementation
1class Solution: 2 def maxValue(self, n: int, index: int, maxSum: int) -> int: 3 def calculate_sum(peak_value: int, count: int) -> int: 4 """ 5 Calculate the sum of a sequence that decreases from peak_value. 6 7 If peak_value >= count: sequence is [peak_value, peak_value-1, ..., peak_value-count+1] 8 If peak_value < count: sequence is [peak_value, peak_value-1, ..., 1, 1, 1, ...] 9 """ 10 if peak_value >= count: 11 return (peak_value + peak_value - count + 1) * count // 2 12 else: 13 return (peak_value + 1) * peak_value // 2 + count - peak_value 14 15 def exceeds_budget(mid: int) -> bool: 16 """Check if placing value 'mid' at index exceeds maxSum.""" 17 total_sum = calculate_sum(mid - 1, index) + calculate_sum(mid, n - index) 18 return total_sum > maxSum 19 20 # Binary search for the first value that exceeds budget 21 # Answer will be first_true_index - 1 (last valid value) 22 left, right = 1, maxSum + 1 23 first_true_index = -1 24 25 while left <= right: 26 mid = (left + right) // 2 27 if exceeds_budget(mid): 28 first_true_index = mid 29 right = mid - 1 30 else: 31 left = mid + 1 32 33 # If first_true_index is found, answer is the value just before it 34 # If first_true_index is -1, all values are valid, return maxSum 35 return first_true_index - 1 if first_true_index != -1 else maxSum 361class Solution { 2 public int maxValue(int n, int index, int maxSum) { 3 // Binary search for the first value that exceeds budget 4 // Answer will be firstTrueIndex - 1 (last valid value) 5 int left = 1; 6 int right = maxSum + 1; 7 int firstTrueIndex = -1; 8 9 while (left <= right) { 10 int mid = left + (right - left) / 2; 11 if (exceedsBudget(mid, n, index, maxSum)) { 12 firstTrueIndex = mid; 13 right = mid - 1; 14 } else { 15 left = mid + 1; 16 } 17 } 18 19 // If firstTrueIndex is found, answer is the value just before it 20 return firstTrueIndex != -1 ? firstTrueIndex - 1 : maxSum; 21 } 22 23 private boolean exceedsBudget(int mid, int n, int index, int maxSum) { 24 long totalSum = calculateSum(mid - 1, index) + calculateSum(mid, n - index); 25 return totalSum > maxSum; 26 } 27 28 private long calculateSum(long peakValue, int count) { 29 if (peakValue >= count) { 30 return (peakValue + peakValue - count + 1) * count / 2; 31 } else { 32 return (peakValue + 1) * peakValue / 2 + count - peakValue; 33 } 34 } 35} 361class Solution { 2public: 3 int maxValue(int n, int index, int maxSum) { 4 auto calculateSum = [](long peakValue, int count) { 5 if (peakValue >= count) { 6 return (peakValue + peakValue - count + 1) * count / 2; 7 } else { 8 return (peakValue + 1) * peakValue / 2 + count - peakValue; 9 } 10 }; 11 12 auto exceedsBudget = [&](int mid) { 13 long totalSum = calculateSum(mid - 1, index) + calculateSum(mid, n - index); 14 return totalSum > maxSum; 15 }; 16 17 // Binary search for the first value that exceeds budget 18 // Answer will be firstTrueIndex - 1 (last valid value) 19 int left = 1; 20 int right = maxSum + 1; 21 int firstTrueIndex = -1; 22 23 while (left <= right) { 24 int mid = left + (right - left) / 2; 25 if (exceedsBudget(mid)) { 26 firstTrueIndex = mid; 27 right = mid - 1; 28 } else { 29 left = mid + 1; 30 } 31 } 32 33 return firstTrueIndex != -1 ? firstTrueIndex - 1 : maxSum; 34 } 35}; 361function maxValue(n: number, index: number, maxSum: number): number { 2 const calculateSum = (peakValue: number, count: number): number => { 3 if (peakValue >= count) { 4 return (peakValue + peakValue - count + 1) * count / 2; 5 } else { 6 return (peakValue + 1) * peakValue / 2 + count - peakValue; 7 } 8 }; 9 10 const exceedsBudget = (mid: number): boolean => { 11 const totalSum = calculateSum(mid - 1, index) + calculateSum(mid, n - index); 12 return totalSum > maxSum; 13 }; 14 15 // Binary search for the first value that exceeds budget 16 // Answer will be firstTrueIndex - 1 (last valid value) 17 let left = 1; 18 let right = maxSum + 1; 19 let firstTrueIndex = -1; 20 21 while (left <= right) { 22 const mid = Math.floor((left + right) / 2); 23 if (exceedsBudget(mid)) { 24 firstTrueIndex = mid; 25 right = mid - 1; 26 } else { 27 left = mid + 1; 28 } 29 } 30 31 return firstTrueIndex !== -1 ? firstTrueIndex - 1 : maxSum; 32} 33Solution Approach
The solution uses the binary search template to find the maximum value at nums[index]. The key insight is to search for the first value that exceeds the budget, then return the value just before it.
Helper Function: calculateSum(peakValue, count)
This function calculates the sum of a decreasing sequence starting from peakValue with count elements:
-
Case 1: When
peakValue >= count- All elements can decrease by 1 without reaching below 1- The sequence is:
[peakValue, peakValue-1, ..., peakValue-count+1] - Sum =
(peakValue + peakValue - count + 1) * count / 2
- The sequence is:
-
Case 2: When
peakValue < count- The sequence reaches 1 before using allcountpositions- Sum =
(peakValue + 1) * peakValue / 2 + (count - peakValue)
- Sum =
Feasible Function: exceedsBudget(mid)
The feasibility condition checks if placing value mid at the index exceeds maxSum:
def exceeds_budget(mid: int) -> bool: total_sum = calculate_sum(mid - 1, index) + calculate_sum(mid, n - index) return total_sum > maxSum
This creates a pattern: false, false, ..., false, true, true, ...
- Values 1, 2, 3, ... are valid (don't exceed budget) → return
false - At some point, values become too large → return
true
Binary Search Template
We use the standard template to find the first value where exceeds_budget returns true:
left, right = 1, maxSum + 1 first_true_index = -1 while left <= right: mid = (left + right) // 2 if exceeds_budget(mid): first_true_index = mid right = mid - 1 else: left = mid + 1 return first_true_index - 1 if first_true_index != -1 else maxSum
The answer is first_true_index - 1 because we want the last valid value (the one just before the first invalid value).
The time complexity is O(log(maxSum)) for the binary search, with O(1) for each validation check. Space complexity is O(1).
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 a concrete example with n = 6, index = 2, and maxSum = 9.
We want to find the maximum value we can place at position 2 in an array of length 6, where the total sum cannot exceed 9.
Step 1: Set up binary search bounds
left = 1(minimum possible value)right = 9(theoretical maximum)
Step 2: First iteration - try mid = 5
- Place 5 at index 2
- Build the array following the "hill" pattern:
- Position 2: value = 5
- Position 1: value = 4 (decrease by 1)
- Position 0: value = 3 (decrease by 1)
- Position 3: value = 4 (decrease by 1)
- Position 4: value = 3 (decrease by 1)
- Position 5: value = 2 (decrease by 1)
- Array:
[3, 4, 5, 4, 3, 2] - Calculate sum using helper function:
- Left side (2 elements):
sum(4, 2) = 4 + 3 = 7 - Right side (4 elements):
sum(5, 4) = 5 + 4 + 3 + 2 = 14 - Total = 7 + 14 = 21
- Left side (2 elements):
- Since 21 > 9, this is too large. Update
right = 4
Step 3: Second iteration - try mid = 3
- Place 3 at index 2
- Build the array:
- Position 2: value = 3
- Position 1: value = 2
- Position 0: value = 1
- Position 3: value = 2
- Position 4: value = 1
- Position 5: value = 1 (can't go below 1)
- Array:
[1, 2, 3, 2, 1, 1] - Calculate sum:
- Left side:
sum(2, 2) = 2 + 1 = 3 - Right side:
sum(3, 4) = 3 + 2 + 1 + 1 = 7 - Total = 3 + 7 = 10
- Left side:
- Since 10 > 9, still too large. Update
right = 2
Step 4: Third iteration - try mid = 2
- Place 2 at index 2
- Build the array:
- Position 2: value = 2
- Position 1: value = 1
- Position 0: value = 1 (can't go below 1)
- Position 3: value = 1
- Position 4: value = 1
- Position 5: value = 1
- Array:
[1, 1, 2, 1, 1, 1] - Calculate sum:
- Left side:
sum(1, 2) = 1 + 1 = 2 - Right side:
sum(2, 4) = 2 + 1 + 1 + 1 = 5 - Total = 2 + 5 = 7
- Left side:
- Since 7 ≤ 9, this is valid! Update
left = 2
Step 5: Check convergence
- Now
left = 2andright = 2 - Binary search converges
Answer: 2
The maximum value we can place at index 2 is 2, resulting in the array [1, 1, 2, 1, 1, 1] with sum 7, which satisfies all constraints.
Time and Space Complexity
The time complexity of this algorithm is O(log maxSum). The binary search operates on the range [1, maxSum], where left = 1 and right = maxSum. In each iteration, the search space is halved by updating either left = mid or right = mid - 1. The number of iterations required is therefore log₂(maxSum), which gives us O(log maxSum) time complexity.
The sum helper function performs constant time operations with arithmetic calculations that don't depend on the input size. Each call to sum within the binary search loop takes O(1) time.
The space complexity is O(1). The algorithm only uses a fixed number of variables (left, right, mid) regardless of the input size. The sum function also uses only local variables (x, cnt) and performs calculations without requiring additional space that scales with the input. No recursive calls are made, and no additional data structures are allocated, resulting in constant space usage.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Using Wrong Binary Search Template Variant
Pitfall: Using the while left < right with left = mid pattern instead of the standard template. This can cause infinite loops and is harder to reason about.
Wrong Implementation:
while left < right: mid = (left + right + 1) >> 1 if total_sum <= maxSum: left = mid else: right = mid - 1 return left
Correct Implementation (using template):
left, right = 1, maxSum + 1 first_true_index = -1 while left <= right: mid = (left + right) // 2 if exceeds_budget(mid): first_true_index = mid right = mid - 1 else: left = mid + 1 return first_true_index - 1 if first_true_index != -1 else maxSum
2. Incorrect Sum Calculation for the Sides
Pitfall: Incorrectly calculating the sum for the left and right sides of the index.
Solution: Remember that we're building a "hill" where:
- The peak is at position
indexwith valuemid - Left side has
indexelements decreasing frommid - 1 - Right side has
n - indexelements starting frommid(including the peak)
3. Integer Overflow in Arithmetic Sequence Formula
Pitfall: When calculating the sum of an arithmetic sequence, the multiplication can cause integer overflow for large values.
Solution: In Python, this isn't typically an issue due to arbitrary precision integers, but in other languages, use long/int64 data types.
4. Forgetting Edge Cases with Zero Elements
Pitfall: Not handling cases where one side has zero elements (when index = 0 or index = n - 1).
Solution: Ensure your helper function properly handles count = 0 case by returning 0.
5. Misunderstanding the Problem Constraints
Pitfall: Assuming the array can have zeros.
Solution: Always use 1 as the minimum value for any array position. The optimal strategy is to decrease by 1 from the peak until reaching 1, then fill remaining positions with 1s.
How would you design a stack which has a function min that returns the minimum element in the stack, in addition to push and pop? All push, pop, min should have running time O(1).
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
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
https assets algo monster cover_photos Binary_Search svg Binary Search Intuition Binary search is an efficient array search algorithm It works by narrowing down the search range by half each time If you have looked up a word in a physical dictionary you've already used binary search in real life Let's
Want a Structured Path to Master System Design Too? Don’t Miss This!