周賽355。似乎很久沒有出貪心題了。

題目

輸入正整數陣列nums。

你可以執行以下操作任意次:

  • 選擇滿足0 <= i < nums.length - 1以及nums[i] <= nums[i+1]的整數i
  • 將nums[i+1]替換成nums[i] + nums[i+1],並將nums[i]從陣列中刪除

求陣列中可以達到的最大元素值為多少。

解法

簡單說就是找兩個相鄰的數a和b,只要a <= b就可以把兩個合併。

假設有三個連續的數字[a,b,c],且滿足a <= b <= c。
如果先讓bc合併,那麼之後一定也可以把a合併過來;如果先讓ab合併了,之後有可能因為過大而無法和c合併。
又假設[a,b,c],其中b > c,那麼無論如何c都不可能變大,之後左邊的數字越來越大,c也就更不可能合併了。
因此得出貪心的結論:從右往左遍歷,可以合併就合併,不能合併就丟掉。

又根據此結論,被丟棄的元素肯定是較小的值,不可能是答案;所以nums中最後剩下的一個元素,若不是被留下的較大值,不然就是兩者合併後的新值,反正他一定是答案。
我們可以直接把nums當做堆疊,模擬上述的過程。

時間複雜度O(N)。
空間複雜度O(1),原地修改輸入。

class Solution:
    def maxArrayValue(self, nums: List[int]) -> int:
        st=nums
        while len(st)>1:
            b=st.pop()
            a=st.pop()
            if a<=b: # merge
                st.append(a+b)
            else: # discard
                st.append(a)
        
        return st[0]