2
// Use stack. Similar to trapping the rain water problem and the largest rectangle under histogram3
// Use stack to keep a decreasing order by adding smaller values, while there is bigger value4
// arr[i] than the peek, pop it and store as mid and calculate the multiplication mid*min(arr[i],7
// NOTE: if we observe the number array, in order to obtain the smallest sum of all non-leaf8
// values, we want to merge those small values first. In order words, the smaller a value9
// is, the lower leaf it should stay because this way as we are building the tree up,10
// we are building smaller multiplication/parent node first as it is only going to get bigger11
// as we build the tree up.14
// There are many ways we can build a tree following the problem's requirement. However, to15
// gain smallest sum. We need to merge 2 and 1 first as they are the two smallest ones. To16
// do that, we use the stack mentioned above as a decreasing order. After17
// that we get a parent node with value 2. This node could be a left or right child of its parent18
// but what we want is that its parent needs also be as small as possible. We also know that its19
// parent has one mutiplier already: 2. Note: this 2 is not from the product of 1 * 2, but from21
// 1 and 2 as the problem requires. So, we see what values next to the leaf 2 could be a22
// candidate. Obviously, 3 since it is the smallest one in the stack Then, 323
// becomes the left child and 1*2 = 2 becomes right child. See below:31
// If we observe carefully, 3 2 1 is decreasing... So how about every time we see a "dip" point32
// in the array we calculate its multiplication. To do that, say we are at arr[i] and their33
// relations are arr[i-1] <= arr[i] <= arr[i+1]. The min multiplication is a[i] * min(arr[i-1],34
// arr[i+1]). Then the example above is arr[i] = 1, arr[i-1] = 2, arr[i+1] = 536
public int mctFromLeafValues(int[] arr) {37
if (arr == null || arr.length < 2) {42
Stack<Integer> stack = new Stack<>();45
// while num is bigger than peek(), pop and calculate46
while (!stack.isEmpty() && stack.peek() <= num) {47
int mid = stack.pop();48
if (stack.isEmpty()) res += mid * num;49
else res += mid * Math.min(stack.peek(), num);52
stack.push(num); // if num is smaller, push into stack55
// if there are values left in the stack, they sure will be mutiplied anyway56
// and added to the result.57
while (stack.size() > 1) { // > 1 because we have a peek() after pop() below58
res += stack.pop() * stack.peek();