import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Objects;
public final class Tree {
private final List<List<Integer>> rows;
private Tree(Builder builder) {
rows = builder.rows;
}
public int computeMaxSum() {
if (rows.isEmpty()) {
return 0;
}
return computeMaxSumIndexed(0, 0, 0);
}
private int computeMaxSumIndexed(int cumulativeSum, int row, int column) {
int currentSum = cumulativeSum + rows.get(row).get(column);
int nextRow = row + 1;
if (nextRow == rows.size()) {
return currentSum;
}
int leftSum = computeMaxSumIndexed(currentSum, nextRow, column);
int rightSum = computeMaxSumIndexed(currentSum, nextRow, column + 1);
return Math.max(leftSum, rightSum);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tree tree = (Tree) o;
return Objects.equals(rows, tree.rows);
}
@Override
public int hashCode() {
return Objects.hash(rows);
}
public static final class Builder {
private final List<List<Integer>> rows;
private Builder() {
rows = Lists.newArrayList();
}
public static Builder aTreeBuilder() {
return new Builder();
}
public Builder withRow(List<Integer> row) {
Preconditions.checkArgument(row.size() == (rows.size() + 1));
rows.add(row);
return this;
}
public Tree build() {
return new Tree(this);
}
}
}