Facebook Pixel

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 Approach

The solution uses binary search to find the maximum value at nums[index]. Let's break down the implementation:

Helper Function: sum(x, cnt)

First, we define a helper function to calculate the sum of a decreasing sequence starting from value x with cnt elements:

  • Case 1: When x >= cnt - All elements can decrease by 1 without reaching below 1

    • The sequence is: [x, x-1, x-2, ..., x-cnt+1]
    • Sum = (x + (x-cnt+1)) * cnt / 2 using arithmetic sequence formula
  • Case 2: When x < cnt - The sequence reaches 1 before using all cnt positions

    • First part: [x, x-1, ..., 2, 1] which has x elements
    • Sum of first part = (x+1) * x / 2
    • Remaining cnt - x elements are all 1s
    • Total sum = (x+1) * x / 2 + (cnt - x)

Binary Search Implementation

  1. Initialize bounds:

    • left = 1 (minimum possible value for any element)
    • right = maxSum (theoretical maximum if we had just one element)
  2. Binary search loop:

    • Calculate mid = (left + right + 1) >> 1 (using bit shift for division by 2)
    • For value mid at position index, calculate minimum array sum:
      • Left side sum: sum(mid - 1, index) - covers positions 0 to index-1
      • Right side sum: sum(mid, n - index) - covers positions index to n-1
      • Total = left side + right side
  3. Decision logic:

    • If total sum ≤ maxSum: Current mid is valid, try larger values (left = mid)
    • If total sum > maxSum: Current mid is too large, search smaller values (right = mid - 1)
  4. Return: When left == right, we've found the maximum valid value

Why This Works

The algorithm correctly handles edge cases:

  • When index = 0 or index = n-1, one side has 0 elements
  • When the optimal value is small, many array positions will have value 1
  • When the optimal value is large, the array forms a perfect pyramid/hill shape

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.

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            Args:
11                peak_value: The starting/peak value of the sequence
12                count: The number of elements in the sequence
13          
14            Returns:
15                The sum of the sequence
16            """
17            if peak_value >= count:
18                # Arithmetic sequence from peak_value down to (peak_value - count + 1)
19                # Sum = (first_term + last_term) * count / 2
20                return (peak_value + peak_value - count + 1) * count // 2
21            else:
22                # Sum of arithmetic sequence from peak_value down to 1, 
23                # plus remaining positions filled with 1s
24                # Sum = (peak_value + 1) * peak_value / 2 + (count - peak_value) * 1
25                return (peak_value + 1) * peak_value // 2 + count - peak_value
26      
27        # Binary search for the maximum value at index position
28        left, right = 1, maxSum
29      
30        while left < right:
31            # Calculate mid point, biased towards right for upper bound search
32            mid = (left + right + 1) >> 1
33          
34            # Calculate total sum with mid as the value at index position
35            # Left side: decreasing from (mid-1) for 'index' positions
36            # Right side: decreasing from mid for (n-index) positions
37            total_sum = calculate_sum(mid - 1, index) + calculate_sum(mid, n - index)
38          
39            if total_sum <= maxSum:
40                # If total sum is within budget, try a larger value
41                left = mid
42            else:
43                # If total sum exceeds budget, try a smaller value
44                right = mid - 1
45      
46        return left
47
1class Solution {
2    /**
3     * Finds the maximum value that can be placed at a given index in an array
4     * such that the array is positive, has adjacent elements differ by at most 1,
5     * and the sum of all elements doesn't exceed maxSum.
6     * 
7     * @param n      The length of the array
8     * @param index  The index where we want to maximize the value
9     * @param maxSum The maximum allowed sum of all array elements
10     * @return The maximum value that can be placed at the given index
11     */
12    public int maxValue(int n, int index, int maxSum) {
13        // Binary search for the maximum possible value at the index
14        int left = 1;
15        int right = maxSum;
16      
17        while (left < right) {
18            // Calculate mid point, using unsigned right shift to avoid overflow
19            int mid = (left + right + 1) >>> 1;
20          
21            // Check if placing 'mid' at index position is valid
22            // Calculate sum of left side (excluding index) and right side (including index)
23            if (sum(mid - 1, index) + sum(mid, n - index) <= maxSum) {
24                // If valid, try to find a larger value
25                left = mid;
26            } else {
27                // If invalid, reduce the search range
28                right = mid - 1;
29            }
30        }
31      
32        return left;
33    }
34
35    /**
36     * Calculates the sum of an arithmetic sequence that starts from x and decreases by 1
37     * for each position, with a minimum value of 1.
38     * 
39     * @param x   The starting value (peak value)
40     * @param cnt The number of elements to sum
41     * @return The sum of the sequence
42     */
43    private long sum(long x, int cnt) {
44        if (x >= cnt) {
45            // If x is large enough, we have a decreasing sequence: x, x-1, x-2, ..., x-cnt+1
46            // Sum = (first + last) * count / 2 = (x + (x - cnt + 1)) * cnt / 2
47            return (x + x - cnt + 1) * cnt / 2;
48        } else {
49            // If x is smaller than cnt, we have: x, x-1, ..., 1, 1, 1, ...
50            // Sum of decreasing part: x + (x-1) + ... + 1 = x*(x+1)/2
51            // Plus remaining 1s: (cnt - x) * 1
52            return (x + 1) * x / 2 + cnt - x;
53        }
54    }
55}
56
1class Solution {
2public:
3    int maxValue(int n, int index, int maxSum) {
4        // Lambda function to calculate the sum of an arithmetic sequence
5        // starting from x and decreasing by 1 each step, for 'count' elements
6        // If x >= count: sum = x + (x-1) + ... + (x-count+1)
7        // If x < count: sum = x + (x-1) + ... + 1 + (count-x) ones
8        auto calculateSum = [](long centerValue, int count) {
9            if (centerValue >= count) {
10                // Arithmetic sequence: x, x-1, ..., x-count+1
11                // Sum = (first + last) * count / 2
12                return (centerValue + centerValue - count + 1) * count / 2;
13            } else {
14                // Arithmetic sequence from x down to 1, then fill remaining with 1s
15                // Sum = x + (x-1) + ... + 1 + (count-x) ones
16                return (centerValue + 1) * centerValue / 2 + count - centerValue;
17            }
18        };
19      
20        // Binary search for the maximum value at index position
21        int left = 1;
22        int right = maxSum;
23      
24        while (left < right) {
25            // Calculate mid point, rounding up
26            int mid = (left + right + 1) >> 1;
27          
28            // Calculate total sum with mid as the value at index position
29            // Left side: elements from index-1 down to 0 (total: index elements)
30            // Right side: elements from index to n-1 (total: n-index elements)
31            long leftSum = calculateSum(mid - 1, index);
32            long rightSum = calculateSum(mid, n - index);
33          
34            if (leftSum + rightSum <= maxSum) {
35                // If total sum is within budget, try a larger value
36                left = mid;
37            } else {
38                // If total sum exceeds budget, try a smaller value
39                right = mid - 1;
40            }
41        }
42      
43        return left;
44    }
45};
46
1function maxValue(n: number, index: number, maxSum: number): number {
2    /**
3     * Calculate the sum of elements in a mountain-like array segment
4     * @param centerValue - The peak value to start from
5     * @param count - Number of elements in the segment
6     * @returns The sum of the segment where values decrease by 1 each step (minimum 1)
7     */
8    const calculateSum = (centerValue: number, count: number): number => {
9        if (centerValue >= count) {
10            // When centerValue is large enough, we have a decreasing sequence
11            // Sum of arithmetic sequence: centerValue, centerValue-1, ..., centerValue-count+1
12            // Formula: (first + last) * count / 2
13            return (centerValue + centerValue - count + 1) * count / 2;
14        } else {
15            // When centerValue is smaller than count, sequence goes down to 1 then stays at 1
16            // Sum = centerValue + (centerValue-1) + ... + 1 + (count-centerValue) ones
17            // Arithmetic sum from centerValue to 1, plus remaining ones
18            return (centerValue + 1) * centerValue / 2 + count - centerValue;
19        }
20    };
21  
22    // Binary search to find the maximum possible value at the index position
23    let left: number = 1;
24    let right: number = maxSum;
25  
26    while (left < right) {
27        // Calculate midpoint, rounding up to avoid infinite loop
28        const mid: number = (left + right + 1) >> 1;
29      
30        // Calculate total sum with mid as the peak value at index
31        // Left segment: from position 0 to index-1 (total of 'index' elements)
32        // Values decrease from mid-1 going leftward
33        const leftSum: number = calculateSum(mid - 1, index);
34      
35        // Right segment: from position index to n-1 (total of 'n-index' elements)  
36        // Values decrease from mid going rightward (including the element at index)
37        const rightSum: number = calculateSum(mid, n - index);
38      
39        if (leftSum + rightSum <= maxSum) {
40            // Total sum is within budget, can try a larger value
41            left = mid;
42        } else {
43            // Total sum exceeds budget, need to try a smaller value
44            right = mid - 1;
45        }
46    }
47  
48    return left;
49}
50

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. Incorrect Sum Calculation for the Sides

Pitfall: A common mistake is incorrectly calculating the sum for the left and right sides of the index. Developers often forget that:

  • The left side should start from mid - 1 (one less than the peak)
  • The right side should start from mid (including the peak itself)

Wrong Implementation:

# Incorrect: both sides starting from mid
total_sum = calculate_sum(mid, index) + calculate_sum(mid, n - index)

# Or incorrect: not accounting for the peak value properly
total_sum = mid + calculate_sum(mid - 1, index) + calculate_sum(mid - 1, n - index - 1)

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)

2. Integer Overflow in Arithmetic Sequence Formula

Pitfall: When calculating the sum of an arithmetic sequence, the multiplication can cause integer overflow for large values:

# Potential overflow for large peak_value and count
return (peak_value + peak_value - count + 1) * count // 2

Solution: In Python, this isn't typically an issue due to arbitrary precision integers, but in other languages, consider:

  • Using long/int64 data types
  • Rearranging the formula to minimize intermediate values
  • Breaking the calculation into smaller parts

3. Off-by-One Error in Binary Search

Pitfall: Using the wrong binary search pattern, especially with the mid calculation:

# Wrong: might cause infinite loop
mid = (left + right) // 2  # Instead of (left + right + 1) // 2

Solution: When searching for the maximum valid value (upper bound), use:

  • mid = (left + right + 1) >> 1 to bias toward the upper half
  • Update left = mid when valid, right = mid - 1 when invalid
  • This prevents infinite loops when left and right are adjacent

4. Forgetting Edge Cases with Zero Elements

Pitfall: Not handling cases where one side has zero elements (when index = 0 or index = n - 1):

# This could fail if index = 0 (left side has 0 elements)
left_sum = calculate_sum(mid - 1, index)  # index could be 0

Solution: The current implementation handles this correctly because calculate_sum(x, 0) returns 0, but ensure your helper function properly handles count = 0 case:

def calculate_sum(peak_value: int, count: int) -> int:
    if count == 0:
        return 0
    # ... rest of the function

5. Misunderstanding the Problem Constraints

Pitfall: Assuming the array can have zeros or that we need to minimize other positions:

# Wrong: trying to use 0s to minimize sum
# The problem states all elements must be positive (at least 1)

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.

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

Consider the classic dynamic programming of longest increasing subsequence:

Find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order.

For example, the length of LIS for [50, 3, 10, 7, 40, 80] is 4 and LIS is [3, 7, 40, 80].

What is the recurrence relation?


Recommended Readings

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

Load More