Problem Statement
Given an integer array arr[], we are allowed to replace any number of elements with 1.
Our goal is to find the maximum possible sum of absolute differences between consecutive elements after making any number of replacements.
For example:
arr = [3, 2, 1, 4, 5]The adjacent differences are:
|3 - 2| + |2 - 1| + |1 - 4| + |4 - 5|
= 1 + 1 + 3 + 1
= 6But we can replace some elements with 1.
For example:
[3, 1, 1, 4, 1]Now:
|3 - 1| + |1 - 1| + |1 - 4| + |4 - 1|
= 2 + 0 + 3 + 3
= 8Therefore, the answer is:
8Understanding the Problem
For every element, we have exactly two choices:
Choice 1: Keep the original value
For example:
arr[i] = 4We can keep it as:
4Choice 2: Replace it with 1
We can change:
4 → 1So every element has two possible states:
Original value
OR
1This naturally suggests Dynamic Programming.
Why Greedy Is Difficult
At first, it might seem that we should simply replace every element with 1.
But that is not always optimal.
Consider:
[1, 5]If we don't modify anything:
|1 - 5| = 4If we replace 5 with 1:
|1 - 1| = 0So replacing an element can actually reduce the answer.
The decision for one element also affects the difference with both its neighbors.
Therefore, we need to consider both possibilities using Dynamic Programming.
DP States
We maintain two DP values.
dp0
dp0 represents:
Maximum sum obtained so far when the current element is kept unchanged.
For example, if the current element is:
arr[i] = 4then the current value is 4.
dp1
dp1 represents:
Maximum sum obtained so far when the current element is replaced by
1.
So if:
arr[i] = 4then the current value becomes:
1Transition
Suppose we are currently processing:
arr[i]There are two possibilities.
Case 1: Keep arr[i]
The current value is:
arr[i]The previous element could have been:
Previous element was unchanged
Previous value:
arr[i - 1]Difference:
|arr[i] - arr[i - 1]|Total:
dp0 + |arr[i] - arr[i - 1]|Previous element was replaced
Previous value:
1Difference:
|arr[i] - 1|Total:
dp1 + |arr[i] - 1|Therefore:
newDp0 = max(
dp0 + |arr[i] - arr[i - 1]|,
dp1 + |arr[i] - 1|
)Case 2: Replace arr[i] with 1
Now the current value is:
1Again, there are two possibilities for the previous element.
Previous element was unchanged
Previous value:
arr[i - 1]Difference:
|1 - arr[i - 1]|Total:
dp0 + |1 - arr[i - 1]|Previous element was also replaced
Both values are 1.
Therefore:
|1 - 1| = 0Total:
dp1 + 0So:
newDp1 = max(
dp0 + |1 - arr[i - 1]|,
dp1
)Java Implementation
class Solution {
public int maxDiffSum(int[] arr) {
int n = arr.length;
if (n <= 1) {
return 0;
}
// Current element is NOT replaced
long dp0 = 0;
// Current element IS replaced with 1
long dp1 = 0;
for (int i = 1; i < n; i++) {
long newDp0 = Math.max(
dp0 + Math.abs(arr[i] - arr[i - 1]),
dp1 + Math.abs(arr[i] - 1)
);
long newDp1 = Math.max(
dp0 + Math.abs(1 - arr[i - 1]),
dp1
);
dp0 = newDp0;
dp1 = newDp1;
}
return (int) Math.max(dp0, dp1);
}
}Code Explanation
Let's understand the code line by line.
Step 1: Array Size
int n = arr.length;This stores the number of elements in the array.
Step 2: Handle One Element
if (n <= 1) {
return 0;
}If there is only one element, there are no consecutive pairs.
For example:
[5]There is no adjacent difference.
Therefore:
answer = 0Step 3: Initialize DP
long dp0 = 0;
long dp1 = 0;Initially, there is no adjacent pair.
So both states start from 0.
dp0 = current element kept
dp1 = current element changed to 1We use long internally so that the calculation is safe for larger sums.
Step 4: Traverse the Array
for (int i = 1; i < n; i++) {We start from index 1 because we need a previous element to calculate:
|arr[i] - arr[i - 1]|Step 5: Calculate newDp0
long newDp0 = Math.max(
dp0 + Math.abs(arr[i] - arr[i - 1]),
dp1 + Math.abs(arr[i] - 1)
);This calculates the best answer when the current element is not replaced.
There are two possibilities.
Previous was unchanged
dp0 + Math.abs(arr[i] - arr[i - 1])Previous was replaced
dp1 + Math.abs(arr[i] - 1)We take whichever is larger:
Math.max(...)Step 6: Calculate newDp1
long newDp1 = Math.max(
dp0 + Math.abs(1 - arr[i - 1]),
dp1
);This calculates the best answer when the current element is replaced with 1.
Again, two possibilities.
Previous was unchanged
dp0 + Math.abs(1 - arr[i - 1])Previous was replaced
The previous value is 1 and current value is also 1.
Therefore:
|1 - 1| = 0So we simply have:
dp1Step 7: Move to the Next Position
dp0 = newDp0;
dp1 = newDp1;The newly calculated states become the previous states for the next iteration.
This is what allows us to solve the problem using only two variables instead of a complete DP array.
Step 8: Return the Maximum
return (int) Math.max(dp0, dp1);At the end, the final element can either be:
original valueor:
1Therefore, we take the maximum of:
dp0
dp1Dry Run
Consider:
arr = [3, 2, 1, 4, 5]Initially:
dp0 = 0
dp1 = 0i = 1
Current:
arr[1] = 2Keep 2:
newDp0 = max(
0 + |2 - 3|,
0 + |2 - 1|
)
= max(1, 1)
= 1Replace 2 with 1:
newDp1 = max(
0 + |1 - 3|,
0
)
= max(2, 0)
= 2Now:
dp0 = 1
dp1 = 2i = 2
Current:
arr[2] = 1Keep 1:
newDp0 = max(
1 + |1 - 2|,
2 + |1 - 1|
)
= max(2, 2)
= 2Replace with 1:
newDp1 = max(
1 + |1 - 2|,
2
)
= max(2, 2)
= 2Now:
dp0 = 2
dp1 = 2i = 3
Current:
arr[3] = 4Keep 4:
newDp0 = max(
2 + |4 - 1|,
2 + |4 - 1|
)
= max(5, 5)
= 5Replace with 1:
newDp1 = max(
2 + |1 - 1|,
2
)
= 2Now:
dp0 = 5
dp1 = 2i = 4
Current:
arr[4] = 5Keep 5:
newDp0 = max(
5 + |5 - 4|,
2 + |5 - 1|
)
= max(6, 6)
= 6Replace with 1:
newDp1 = max(
5 + |1 - 4|,
2
)
= max(8, 2)
= 8Finally:
dp0 = 6
dp1 = 8Therefore:
answer = max(6, 8)
= 8Why the Answer Becomes 8
The DP effectively discovers the optimal modified array:
[3, 1, 1, 4, 1]The sum is:
|3 - 1| = 2
|1 - 1| = 0
|1 - 4| = 3
|4 - 1| = 3Total:
2 + 0 + 3 + 3 = 8Example 2
Consider:
arr = [1, 5]Without modification:
|1 - 5| = 4The DP will compare:
Keep 5:
|1 - 5| = 4and:
Replace 5:
|1 - 1| = 0Therefore:
answer = 4Complexity
There are n elements and we process each element exactly once.
Time Complexity
O(n)For:
n = 100000this is efficient.
Space Complexity
Although a traditional DP solution could use an array and require:
O(n)space, this implementation only stores the previous two states:
dp0
dp1Therefore, the actual auxiliary space is:
O(1)Key Takeaway
The important idea is to recognize that each element has only two possible states:
State 0 → Keep arr[i]
State 1 → Replace arr[i] with 1For every position, we calculate the best result for both states.
The complete DP is:
newDp0 = max(
dp0 + |arr[i] - arr[i-1]|,
dp1 + |arr[i] - 1|
)
newDp1 = max(
dp0 + |1 - arr[i-1]|,
dp1
)This reduces the problem to a simple two-state Dynamic Programming solution.
Final Code
class Solution {
public int maxDiffSum(int[] arr) {
int n = arr.length;
if (n <= 1) {
return 0;
}
long dp0 = 0;
long dp1 = 0;
for (int i = 1; i < n; i++) {
long newDp0 = Math.max(
dp0 + Math.abs(arr[i] - arr[i - 1]),
dp1 + Math.abs(arr[i] - 1)
);
long newDp1 = Math.max(
dp0 + Math.abs(1 - arr[i - 1]),
dp1
);
dp0 = newDp0;
dp1 = newDp1;
}
return (int) Math.max(dp0, dp1);
}
}Interview Tip: When you see a problem where every element has a small number of choices and the current choice depends only on the previous element, think about DP with states. Here, the two states are simply "keep" and "replace with 1".
Summary
The important idea is to recognize that each element has only two possible states: State 0 → Keep arr[i] and State 1 → Replace arr[i] with 1. For every position, we calculate the best result for both states. This reduces the problem to a simple two-state Dynamic Programming solution.

Join the conversation! Your thoughts help the community grow.