## LeetCode-Python-1354. 多次求和构造目标数组（数学 + 模拟法 + 堆）

[1, 1, 1], 和为 3 ，选择下标 1
[1, 3, 1], 和为 5， 选择下标 2
[1, 3, 5], 和为 9， 选择下标 0
[9, 3, 5] 完成

N == target.length
1 <= target.length <= 5 * 10^4
1 <= target[i] <= 10^9

### 缺点：无法通过[1,1000000000]的极端test case

``````class Solution(object):
def isPossible(self, target):
"""
:type target: List[int]
:rtype: bool
"""
from heapq import *
s = sum(target)
target = [-item for item in target]
heapify(target)
while s > len(target):
m = -heappop(target)
new_m = m - (s - m)
if new_m == m:
break
heappush(target, -new_m)
s = s - m + new_m

return not any([num != -1 for num in target])``````

``````class Solution(object):
def isPossible(self, target):
"""
:type target: List[int]
:rtype: bool
"""
from heapq import *
if len(target) == 1 and sum(target) != 1:
return False
s = sum(target)
target = [-item for item in target]
heapify(target)
while s > len(target):
# print target
# 找当前最大的数和第二大的数
m = -heappop(target)
s_m = -heappop(target)
# 更新 m 并更新 s
new_m = m - (s - m)
if m == new_m:
break
s = s - m + new_m
while new_m > s_m:
# 一直处理最大的数直到它比第二大的数小
m = new_m
new_m = new_m - (s - new_m)
s = s - m + new_m

heappush(target, -new_m)
heappush(target, -s_m)

return not any([num != -1 for num in target])``````

``````            # 找当前最大的数和第二大的数
m = -heappop(target)
s_m = -target[0]

# 更新 m
diff = s - m
if not diff:
break
new_m = m - (max(1, (m - s_m) / diff) * diff)``````

max(1, (m - s_m) / diff)），因为至少需要减一次，最多需要将最大值的新值变得比次大值小。

``````class Solution(object):
def isPossible(self, target):
"""
:type target: List[int]
:rtype: bool
"""
from heapq import *
if len(target) == 1:
return target[0] == 1

s = sum(target)
target = [-item for item in target]
heapify(target)

while s > len(target):
# 找当前最大的数和第二大的数
m = -heappop(target)
s_m = -target[0]

# 更新 m 并更新 s
diff = s - m
if not diff:
break
new_m = m - (max(1, (m - s_m) / diff) * diff)
s = s - m + new_m

heappush(target, -new_m)

return not any([num != -1 for num in target])``````