5343. 多次求和构造目标数组
给你一个整数数组 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
解题思路:从目标出发,找出当前最大值max,其必为剩余值得和sum再加其本身原值得到,因此将其位置得值替换为max - sum,进而继续判断,如果判断过程出现替换得值大于1但小于N,说明不可行,或出现max值小于等于sum,也不可行;当出现最大值是1,且其余为和为N-1时说明全为1,输出true。
class Solution {
public:
struct M
{
int k, val;
M(int id, int Length) {
k = id; val = Length;
}
bool operator <(const M& s)const
{
if (val == s.val)
return k > s.k; //最小堆
else
return val < s.val; //最大堆
}
};
priority_queue<M> Room;
bool isPossible(vector<int>& target) {
int N = target.size();
long long Sum = 0;
for (int i = 0; i < N; ++i)
{
Room.push(M(i, target[i]));
Sum += target[i];
}
while (1)
{
M Max_V = Room.top();
Sum -= Max_V.val;
if (Max_V.val == 1 && Sum == N - 1)
return 1;
if (Max_V.val > 1 && Max_V.val < N)
return 0;
if(Max_V.val <= Sum)
return 0;
M New(Max_V.k, Max_V.val - Sum);
if(New.val < 1 || (New.val > 1 && New.val < N))
return 0;
Sum += New.val;
Room.pop();
Room.push(New);
}
}
};