最小化 Array 元素的减法使 X 最多为 0
给定一个数字X和一个包含N个数字的长度为N的数组arr[] 。任务是找到使X为非正数所需的最小操作数。在一次操作中:
- 从数组中选择任意一个数字Y并将X减少Y 。
- 然后使Y = Y/2 (如果 Y 为奇数,则取底值)。
- 如果不可能使X为非正数,则返回-1 。
例子:
Input: N = 3, arr[] = {3, 4, 12}, X = 25
Output: 4
Explanation: Operation 1: Y=12, X reduces to 13, Y becomes 6, arr[]: {3, 4, 6}
Operation 2: Y = 6, X reduces to 7, Y becomes 3, arr[]: {3, 4, 3}
Operation 3: Y = 4, X reduces to 3, Y becomes 2, arr[]: {3, 2, 3}
Operation 4: Y = 3, X reduces to 0, Y becomes 1, arr[]: {1, 2, 3}
Total operations will be 4.
Input: N = 3, arr[] = {11, 11, 110}, X = 11011
Output: -1
Explanation: It is impossible to make X non-positive
方法:这个问题可以使用基于以下思想的max-heap(优先队列)来解决:
To minimze subtraction, it is optimal to subtract the maximum value each time. Fo rthis reaseon use a max-heap so that the maximum value numbers remain on top and perform the operation using the topmost element and keep checking if the number becomes non-positive or not.
请按照下图进行更好的理解。
插图:
Consider arr[] = {3, 4, 12} and X = 25
So max heap (say P) = [3, 4, 12]
1st step:
=> Maximum element (Y) = 12.
=> Subtract 12 from 25. X = 25 – 12 = 13. Y = 12/2 = 6.
=> P = {3, 4, 6}.
2nd step:
=> Maximum element (Y) = 6.
=> Subtract 6 from 13. X = 13 – 6 = 7. Y = 6/2 = 3.
=> P = {3, 3, 4}.
3rd step:
=> Maximum element (Y) = 4.
=> Subtract 4 from 7. X = 7 – 4 = 3. Y = 4/2 = 2.
=> P = {2, 3, 3}.
4th step:
=> Maximum element (Y) = 3.
=> Subtract 3 from 3. X = 3 – 3 = 0. Y = 3/2 = 1.
=> P = {1, 2, 3}.
X is non-positive. So operations required = 4
请按照以下步骤解决问题:
- 创建一个最大堆(由优先级队列实现)并将所有数字存储在其中。
- 执行以下操作,直到优先级队列不为空且X为正。
- 使用具有最大值的数字。这将是优先队列顶部的数字。
- 从优先级队列中删除顶部的数字并执行问题中所述的操作。
- 执行操作后,如果Y为正,则将其添加回优先级队列。
- 每次将答案增加 1。
- 完成上述过程后,如果X为正,则不可能使其为非正,因此返回 -1。
- 否则,返回答案。
下面是上述方法的实现。
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to find minimum operations
int minimumOperations(int N, int X,
vector nums)
{
// Initialize answer as zero
int ans = 0;
// Create Max-Heap using
// Priority-queue
priority_queue pq;
// Put all nums in the priority queue
for (int i = 0; i < N; i++)
pq.push(nums[i]);
// Execute the operation on num with
// max value until nums are left
// and X is positive
while (!pq.empty() and X > 0) {
if (pq.top() == 0)
break;
// Increment the answer everytime
ans++;
// num with maximum value
int num = pq.top();
// Removing the num
pq.pop();
// Reduce X's value and num's
// value as per the operation
X -= num;
num /= 2;
// If the num's value is positive
// insert back in the
// priority queue
if (num > 0)
pq.push(num);
}
// If X's value is positive then it
// is impossible to make X
// non-positive
if (X > 0)
return -1;
// Otherwise return the number of
// operations performed
return ans;
}
// Drivers code
int main()
{
int N = 3;
vector nums = { 3, 4, 12 };
int X = 25;
// Function call
cout << minimumOperations(N, X, nums);
return 0;
}
4
时间复杂度: O(N * log N)
辅助空间: O(N)