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
n
elements - 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]| ≤ 1
for 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
index
ton - 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
- The sequence is:
-
Case 2: When
x < cnt
- The sequence reaches 1 before using allcnt
positions- First part:
[x, x-1, ..., 2, 1]
which hasx
elements - Sum of first part =
(x+1) * x / 2
- Remaining
cnt - x
elements are all 1s - Total sum =
(x+1) * x / 2 + (cnt - x)
- First part:
Binary Search Implementation
-
Initialize bounds:
left = 1
(minimum possible value for any element)right = maxSum
(theoretical maximum if we had just one element)
-
Binary search loop:
- Calculate
mid = (left + right + 1) >> 1
(using bit shift for division by 2) - For value
mid
at positionindex
, 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
- Left side sum:
- Calculate
-
Decision logic:
- If total sum ≤
maxSum
: Currentmid
is valid, try larger values (left = mid
) - If total sum >
maxSum
: Currentmid
is too large, search smaller values (right = mid - 1
)
- If total sum ≤
-
Return: When
left == right
, we've found the maximum valid value
Why This Works
The algorithm correctly handles edge cases:
- When
index = 0
orindex = 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 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 = 2
andright = 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 valuemid
- Left side has
index
elements decreasing frommid - 1
- Right side has
n - index
elements starting frommid
(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
andright
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.
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
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
Binary Search Speedrun For each of the Speedrun questions you will be given a binary search related problem and a corresponding multiple choice question The multiple choice questions are related to the techniques and template s introduced in the binary search section It's recommended that you have gone through at
Want a Structured Path to Master System Design Too? Don’t Miss This!