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 construct
  • index: 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:

  1. Length constraint: The array must have exactly n elements
  2. Positive values: All elements must be positive integers (at least 1)
  3. Adjacent difference constraint: The absolute difference between any two adjacent elements must be at most 1. In other words, |nums[i] - nums[i+1]| ≤ 1 for all valid i
  4. Sum constraint: The sum of all elements cannot exceed maxSum
  5. 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.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

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 index to n - 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 36
1class 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} 36
1class 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}; 36
1function 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} 33

Solution 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
  • Case 2: When peakValue < count - The sequence reaches 1 before using all count positions

    • Sum = (peakValue + 1) * peakValue / 2 + (count - peakValue)

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 Evaluator

Example 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
  • 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
  • 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
  • Since 7 ≤ 9, this is valid! Update left = 2

Step 5: Check convergence

  • Now left = 2 and right = 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 index with value mid
  • Left side has index elements decreasing from mid - 1
  • Right side has n - index elements starting from mid (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.

Loading...
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

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

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More