You can keep an array to keep track of the index of elements
which is used to add to the current element
.
I have modified your code with a parent array to keep track of that. Also, I have changed some variable names (as per my understanding).
public static void maxSum(int[] arr){
int n = arr.length;
int[] parent = new int[n];
parent[0] = -1;
int lastSum = 0; // last sum encountered
int lastPos = -1; // position of that last sum
int currSum = arr[0]; // current sum
int currPos = 0; // position of the current sum
for (int i = 1; i < n; i++) {
parent[i] = lastPos; // save the last sum's position for this element
// below this it is mostly similar to what you have done;
// just keeping track of position too.
int probableSum = Integer.max(arr[i] + lastSum, arr[i]);
int tSum = currSum;
int tPos = currPos;
if(probableSum > currSum){
currSum = probableSum;
currPos = i;
}
lastSum = tSum;
lastPos = tPos;
}
System.out.println(currSum); // print sum
System.out.println(Arrays.toString(parent)); // print parent array; for debugging purposes.
// logic to print the elements
int p = parent[n - 1];
System.out.print(arr[n - 1] + " ");
while (p != -1) {
System.out.print(arr[p] + " ");
p = parent[p];
}
}
I believe code can be cleaned up a lot, but that's an exercise for later :)
Output:
{1,2,3,-1,-3,2,5} => 5 3 1
{4,5,4,3} => 3 5
Update. Added some code explanation
The value of lastSum
& currSum
changes within the execution of the loop. They are best understood by observing how their value changes inside the loop.
During the start of the i
th iteration of the loop lastSum
holds the largest value that can be added to the i
th element; so basically largest value that can be obtained by iterating upto i-2
th element.
currSum
holds the largest value that can be obtained by iterating upto i-1
th element.
At the end of the loop lastSum
is added to the i
th element and is designated as currSum
. If lastSum
is smaller than 0, then i
th element itself is designated as currSum
. And old value of currSum
is now called lastSum
lastPos
& currPos
holds latest index of thier respective sum values.
In all the states shown below for each iteration, the rightmost sum represents currSum
at the start of the iteration. Value to the left of currSum
represents lastSum
. Their index position is recorded in currPos
& lastPos
respectively.
par[]
holds the value of the last index of lastSum
used. This array is later used to construct the actual set of elements which forms largest non-adjacent sum.
initially
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1
par = -1
i=1 iteration state
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, ?
par = -1, !
// before update
currSum = 1, currPos = 0
lastSum = 0, lastPos = -1
// updating
par[1] = lastPos = -1
probableSum = max(2 + 0, 2) = 2 // max(arr[i] + lastSum, arr[i])
? = max(1, 2) = 2 // max(currSum, probableSum)
! = i = 1
// after update
lastSum = currSum = 1
lastPos = currPos = 0
currSum = ? = 2
currPos = ! = 1
i=2 iteration state
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, 2 ?
par = -1, -1 !
// before update
currSum = 2, currPos = 1
lastSum = 1, lastPos = 0
// updating
par[2] = lastPos = 0
probableSum = max(3 + 1, 3) = 4 // max(arr[i] + lastSum, arr[i])
? = max(2, 4) = 4 // max(currSum, probableSum)
! = i = 2
// after update
lastSum = currSum = 2
lastPos = currPos = 1
currSum = ? = 4
currPos = ! = 2
i = 3 iteration state
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, 2 4 ?
par = -1, -1 0 !
// before update
currSum = 4, currPos = 2
lastSum = 2, lastPos = 1
//updating
par[3] = lastpos = 1
probableSum = max(-1 + 2, -1) = 1 // max(arr[i] + lastSum, arr[i])
? = max(4, 1) = 4 // max(currSum, probableSum) ; no update in ?'s value
! = currPos = 2 // as ?'s value didn't update
// after update
lastSum = currSum = 4
lastPos = currPos = 2
currSum = ? = 4
currPos = ! = 2
i = 4 iteration
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, 2 4 4 ?
par = -1, -1 0 1 !
// before update
currSum = 4, currPos = 2
lastSum = 4, lastPos = 2
// updating
par[4] = lastPos = 2
probableSum = max(-3 + 4, -3) = 1 // max(arr[i] + lastSum, arr[i])
? = max(4, 1) = 4 // max(currSum, probableSum) ; no update in ?'s value
! = currPos = 2 // as ?'s value didn't update
// after update
lastSum = currSum = 4
lastPos = currPos = 2
currPos = ? = 4
currPos = ! = 2
i = 5 iteration
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, 2 4 4 4 ?
par = -1, -1 0 1 2 !
// before update
currSum = 4, currPos = 2
lastSum = 4, lastPos = 2
// updating
par[5] = lastPos = 2
probableSum = max(2 + 4, 2) = 6 // max(arr[i] + lastSum, arr[i])
? = max(4, 6) = 6 // max(currSum, probableSum)
! = i = 5
// after update
lastSum = currSum = 4
lastPos = currPos = 2
currPos = ? = 6
currPos = ! = 5
i = 6 iteration state
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, 2 4 4 4 6 ?
par = -1, -1 0 1 2 2 !
// before update
currSum = 6, currPos = 5
lastSum = 4, lastPos = 2
// updating
par[6] = lastPos = 2
probableSum = max(5 + 4, 5) = 9 // max(arr[i] + lastSum, arr[i])
? = max(6, 9) = 9 // max(currSum, probableSum)
! = i = 6
// after update
lastSum = currSum = 6
lastPos = currPos = 5
currPos = ? = 9
currPos = ! = 6
after all iteration state
idx = -1, 0, 1, 2, 3, 4, 5, 6
arr = 0, 1, 2, 3, -1, -3, 2, 5
sum = 0 1, 2 4 4 4 6 9
par = -1, -1 0 1 2 2 2
By using the par[] and looping until par[p] != -1 we can get the index of elements which actually forms set of actual required elements. Check out the code its straight forward.
e.g.
p = last = 6
arr[p] = arr[6] = 5 // element
p = par[p] = par[6] = 2
arr[p] = arr[2] = 3 // element
p = par[p] = par[2] = 0
arr[p] = arr[0] = 1 // element
p = par[p] = par[0] = -1 // stop