Leetcode 1354:多次求和构造目标数组(超详细的解法!!!)

给你一个整数数组 target 。一开始,你有一个数组 A ,它的所有元素均为 1 ,你可以执行以下操作:

  • x 为你数组里所有元素的和
  • 选择满足 0 <= i < target.size 的任意下标 i ,并让 A 数组里下标为 i 处的值为 x
  • 你可以重复该过程任意次

如果能从 A 开始构造出目标数组 target ,请你返回 True ,否则返回 False 。

示例 1:

输入:target = [9,3,5]
输出:true
解释:从 [1, 1, 1] 开始
[1, 1, 1], 和为 3 ,选择下标 1
[1, 3, 1], 和为 5, 选择下标 2
[1, 3, 5], 和为 9, 选择下标 0
[9, 3, 5] 完成

示例 2:

输入:target = [1,1,1,2]
输出:false
解释:不可能从 [1,1,1,1] 出发构造目标数组。

示例 3:

输入:target = [8,5]
输出:true

提示:

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

解题思路

这个问题可以从后向前处理,每次取出目标数组中的最大值,那么这个最大值必然是上一次数组的和替换后得到的。我们假设数组和为 s s s,而上一次数组的和为 p r e pre pre,那么上一次被替换的数字大小为 p r e − ( s − p r e ) = 2 ∗ p r e − s pre-(s-pre)=2*pre-s pre(spre)=2pres,然后这个数放入数组中继续迭代下去。如果最大值为负数,那么表示失败;如果最大值为1,那么表示成功。

例如,第一个例子,此时的最大值为9,可以计算出替换前的数为2*9-17=1,将1放入数组,取出下一个最大值5继续计算。

由于每次都取最大值,所以我们可以使用最大堆处理。

class Solution:
    def isPossible(self, target: List[int]) -> bool:
        q, s = [], 0
        for i in target:
            heapq.heappush(q, -i)
            s += i

        while True:
            pre = -heapq.heappop(q)
            if pre == 1:
                return True
            
            if pre*2 - s < 0:
                return False
            heapq.heappush(q, s - pre*2)
            s = pre

但实际上上面这个写法会超时,对于这样的例子[1e9, 1]

很容易发现问题所在,当一个数非常大的时候减去其他非常小的数的和,结果依旧是最大值。那么可以通过取模计算上一次被替换的数字大小 p r e % ( s − p r e ) pre\%(s-pre) pre%(spre)

此时的边界条件也需做一点调整,如果 p r e < s pre < s pre<s或者 p r e % s = 0 pre\%s=0 pre%s=0说明无解;如果 p r e = 1 pre=1 pre=1或者 s = 1 s=1 s=1说明有解。

class Solution:
    def isPossible(self, target: List[int]) -> bool:
        q, s = [], 0
        for i in target:
            heapq.heappush(q, -i)
            s += i

        while 1:
            pre = -heapq.heappop(q)
            s -= pre
            if pre == 1 or s == 1:
                return True
            if pre < s or pre % s == 0:
                return False
            
            pre %= s
            s += pre
            heapq.heappush(q, -pre)

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(leetcode解题指南,Problems)