題目連結:
題目意譯:
你被給定一個索引值從 0 開始的陣列 nums,其由正整數所組成。
你可以在陣列上做任意次以下的操作:
選擇一個整數 i 使得 0 ≦ i < nums.length - 1 且 nums[i] ≦ nums[i + 1]。將 nums[i + 1] 替換成 nums[i] + nums[i + 1] 並將 nums[i] 這個元素從陣列中刪除。
回傳在最終的陣列裡你可以得到的最大元素值。
限制:
1 ≦ nums.length ≦ 10 ^ 5
1 ≦ nums[i] ≦ 10 ^ 6
範例測資:
範例 1:
輸入: nums = [2,3,7,9,3]
輸出: 21
解釋: 我們可以對陣列套用以下操作:
- 選擇 i = 0。結果陣列將會是 nums = [5,7,9,3]。
- 選擇 i = 1。結果陣列將會是 nums = [5,16,3]。
- 選擇 i = 0。結果陣列將會是 nums = [21,3]。
最終的陣列裡最大的元素為 21。可以證明我們不可能得到更大的元素。
範例 2:
輸入: nums = [5,3,3]
輸出: 11
解釋: 我們可以對陣列套用以下操作:
- 選擇 i = 1。結果陣列將會是 nums = [5,6]。
- 選擇 i = 0。結果陣列將會是 nums = [11]。
最終的陣列裡只有一個元素,其為 11。
解題思維:
假設現在有一個數列是 a1 、 a2 、 …… 、 ak,而這個數列可以根據題目定義的操作來變成單一一個元素 X。
可以看到這個數列可能會有很多種合法的操作執行順序(即可以成功做到只剩一個元素存在),但是有一種順序是不管什麼數列必定會合法的——也就是從結尾反著做到開頭。以索引值表示就會像是
選擇 i = ak-1,數列變成 a1 、 a2 、 …… 、 ak-2 、 ak-1 + ak;
選擇 i = ak-2,數列變成 a1 、 a2 、 …… 、 ak-3 、 ak-2 + ak-1 + ak;
……
以此類推。
反過來說,假設我們現在只知道 X 這個「結果」。並且假設陣列中 X 的位置左邊還有一個元素 Y,即陣列會是 [……, Y, X, ……]。則此時如果 Y ≦ X,我們便可以繼續把這個數字「吃掉」;反之,就算把 X 變為原本的數列然後在最前面加上 Y 值,也不存在任何操作順序可以把 Y 吃掉。
因此我們可以從 nums 的結尾元素開始一直往左「吃」,一路吃到吃不了(即此時的總和值小過目前看到的數字 nums[i])或是遇到了陣列開頭為止。而停下來時的總和會是包含 nums 結尾元素中的所有數列經過操作可以得到的最大值(注意,這不代表這是全域最大值。因為 nums 中可能還有其他數字存在)。
把得到的這個總和丟掉之後,如果 nums 中還有元素存在就重複以上的動作。
最後,所求即為上述過程中得到的各個總和值中的最大者。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。