前往
大廳
主題

LeetCode - 1354. Construct Target Array With Multiple Sums 解題心得

Not In My Back Yard | 2021-06-07 00:00:03 | 巴幣 0 | 人氣 189

題目連結:


題目意譯:
你被給定一個有著 n 個整數的陣列 target。從由 n 個 1 組成的起始陣列 arr 開始,你可以執行以下程序:
令 x 為當前陣列元素之總和。
選擇一個索引值 i,滿足 0 ≦ i < n 並將 arr 索引值 i 的位置之值設為 x 。

如果必要的話,你可以重複此程序任意次。

回傳真(True)如果有可能從 arr 建立出陣列 target;反之,回傳假(False)。

限制:
n == target.length
1 ≦ n ≦ 5 × 10 ^ 4
1 ≦ target[i] ≦ 10 ^ 9



範例測資:
範例 1:
輸入: target = [9,3,5]
輸出: true
解釋: 開始於 arr = [1, 1, 1]
[1, 1, 1] ,總和 = 3 並選擇索引值 1
[1, 3, 1] ,總和 = 3 並選擇索引值 2
[1, 3, 5] ,總和 = 3 並選擇索引值 0
[9, 3, 5] ,結束

範例 2:
輸入: target = [1,1,1,2]
輸出: false
解釋: 不可能從 [1,1,1,1] 製造出陣列 target。

範例 3:
輸入: target = [8,5]
輸出: true


解題思維:
以範例輸入 target = [9,3,5] 為例:
從 [1,1,1] 到 [9,3,5] 可能看不出所以然;但是當我們從 [9,3,5] 試圖反向回去時,可以看到會比較容易。因為:
很明顯地,每一次操作後的陣列元素總和永遠都是遞增的,而且會大於陣列中所有的元素。

因此 [9,3,5] 中的 9,是前一個陣列的總和,而 3 跟 5 存在於前一個陣列。所以我們可以推出前一個陣列為 [1,3,5] 。

類似地,可以看到 [1,3,5] 來自於 [1,3,1] ;而該陣列又可推回到 [1,1,1] 。

因為我們可以回到 [1,1,1],也代表著我們可以順向地製造出 [9,3,5] 。



換以 target = [1,1,1,2] 為例:
陣列中最大的數字為 2,但是同時其他三個 1 又要在前一個陣列裡。三個 1 總和為 3 ,而 3 ≧ 2 ,所以我們無法再往回推了。而因為結果不是 [1,1,1,1] ,所以代表我們無法從 [1,1,1,1] 抵達 [1,1,1,2] 。

所以可以看到我們需要重複「回推」的步驟,直到我們遇到陣列中的最大值 < 其他數字之和。然後看結果的陣列是否全為 1 。

不過值得注意的是當 target = [1,1,50000] 這種情況時,我們如果按照上面的步驟會得到
[1,1,50000]
→ [1,1,49998]
→ [1,1,49996]
→ [1,1,49994]
……
可以看到,最大值總是出現在同一個位置上。而如果按照原本的作法這樣很沒有效率。因此,我們可以直接讓它減小到小於等於其他數字之和(藉由取餘等等操作)。所以上面我們可以直接地從 [1,1,50000] 得到
[1,1,50000 - 2 × 24999]
也就是
[1,1,2]

至於不讓它到 [1,1,0] 是為了避免掉 [1,2] 這種情況。如果直接讓最大變成小於其他數字和,而會得到 [1,0],此時會停止回推,而得到無法從 [1,1] 到 [1,2] 之結論(因為 [1,0] 不是全為 1)。但實際上它是可以從 [1,1] 出發抵達到 [1,2] 的。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作