Problem Description
You are given a 0-indexed array nums of positive integers. You may repeatedly perform the following operation: choose an index i (with 0 ≤ i < nums.length – 1) such that nums[i] ≤ nums[i+1]. Then replace nums[i+1] with nums[i] + nums[i+1] and remove nums[i] from the array. Your goal is to obtain as large an element as possible in the final array. Return the value of the largest element that can eventually occur.
For example, for nums = [2,3,7,9,3] one optimal sequence of operations is: • Merge at i = 0 → [5,7,9,3] • Merge at i = 1 → [5,16,3] • Merge at i = 0 → [21,3] Thus, 21 is the answer.
Key Insights
- The only allowed merge is between two adjacent numbers when the left is no larger than the right.
- Every merge “combines” a contiguous block of numbers; the merged value is the sum of that block.
- Although many merge orders are possible, the final answer is the maximum over all contiguous segments that can be merged (in some legal order).
- A final (non‐mergeable) configuration is equivalent to a partition of the array into segments that were “fully merged” (each merge performed only when the left segment’s value was not greater than the right’s).
- A greedy approach that always picks the rightmost merge candidate can “delay” merging on the left – effectively allowing later merges to “inherit” a larger accumulated sum.
- To implement an optimal (greedy) simulation we can maintain a doubly‐linked list of values along with a “max‐heap” (priority queue) of valid merge candidates (each candidate corresponds to a node whose value is ≤ the value of its next neighbor). Then, repeatedly pick the candidate with the highest index (i.e. the rightmost candidate) to merge. After a merge, update the linked list connections and check whether new merge opportunities have appeared with the neighbor to the left or with the new right neighbor.
Space and Time Complexity
Time Complexity: O(n log n) in the worst case – each merge (of which there are O(n)) performs O(log n) work due to heap updates. Space Complexity: O(n) – for the linked list nodes and the auxiliary heap.
Solution
We simulate the merge operations optimally using a doubly‐linked list so that deleting an element is O(1) and the “neighbors” are always available to update. To always “take” the best opportunity we use a max‐heap keyed by the index of the left node in a valid adjacent merge (i.e. where node.val ≤ node.next.val). (By “max‐heap” the candidate with the highest index – the rightmost valid merge – is processed first.) Each time we remove the right node from the list after merging and update the value of the left node to the sum. Then we check if merging is now possible with the left’s previous neighbor or with its new next neighbor, and if so, add them to the heap. While doing so we keep track of the maximum value ever seen. This maximum will be our answer.
The following code solutions in Python, JavaScript, C++, and Java implement this strategy with detailed comments.