Leetcode 1982 Find Array Given Subset Sums
Leetcode 1982 Find Array Given Subset Sums
這題是從子集合還原成原數組,
提供的集合是所有數組的各集合加總.
例如若原數組 是 {1, 2, 3} 三個數 , n = 3,
各子集合排列組合為 {{}, {1}, {2}, {3}, {1,2}, {1,3}, {2,3}, {1,2,3}}
則提供的 sums 為 {0, 1, 2, 3, 3, 4, 5, 6}
這題有人說是數學題, 而非程式題.
的確沒找到好方法的話, 是過不了這一題的. 時間會超過.
這也正體現有好的演算法, 和沒有的在執行上會有巨大的差距.
雖然 wintel 政策是發展硬體做快速的 CPU 運算
和 更大的記憶體儲存.
但有好的演算法可更加地來利用硬體資源.
方式有很多, 介紹其中一種分析 - 討論
我們先把數列排序後來分析:
{s0, s1, s2, ..., sn}
s1 = s0 + d
拆成
S0: {s0, ... si}
S1: {s0 + d, ... si + d}
並保證空集合{} 的總和 0 , 在處理時, 一直存在數列中.
--
假如 d/-d 不在數組中的話, 因為 s0 / s1 都是數組的組合
(1) 如果 s0 == 0 , s1 = d, 矛盾
(2) 如果 s0 < 0:
如果 s1 > 0, 0 不見了, 矛盾
如果 s1 == 0, s0 = -d, 矛盾
如果 s1 < 0, 表示有其他的 負數 k 不在 s0 中, 則 s0 + k 會比 s0 還小
(3) 如果 s0 > 0, 0 不見了, 矛盾
而因為 S1: {s0 + d, ... si + d}
S1 數列裡的數字 d 的因素就會被消除.
--
例如, 若有個數列 [-355,0,10,44,365,399,409,764]
一開始先用 sums[1] - sums[0] 得到 d = 355
接著可以得到兩群, 是 {Si + 355, ... } 和 與 355 無關的.
留言
張貼留言