5343. 多次求和构造目标数组(Leetcode176周赛)

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);
		}
	}
};
发布了104 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Yanpr919/article/details/104340544