通过重复从一对中减去较小元素来将 Array 减少到 0 的最小操作
给定一个大小为N的数组arr[] ,任务是找到使所有数组元素为零所需的最小操作数。在一个操作中,选择一对元素并从数组中的两个元素中减去较小的元素。
例子:
Input: arr[] = {1, 2, 3, 4}
Output: 3
Explanation: Pick the elements in the following sequence:
Operation 1: Pick elements at indices {3, 2}: arr[]={1, 2, 0, 1}
Operation 2: Pick elements at indices {1, 3}: arr[]={1, 1, 0, 0}
Operation 3: Pick elements at indices {2, 1}: arr[]={0, 0, 0, 0}
Input: arr[] = {2, 2, 2, 2}
Output: 2
方法:这个问题可以使用 优先队列。要解决以下问题,请按照以下步骤操作:
- 遍历数组,将所有大于 0 的元素压入优先队列。
- 创建一个变量op ,用于存储操作数,并将其初始化为 0。
- 现在,遍历优先级队列pq直到它的大小在每次迭代中都大于 1:
- 增加变量op 的值。
- 然后选择前两个元素,比如说p和q来应用给定的操作。
- 应用操作后,一个元素肯定会变为0。如果另一个元素大于零,则将另一个元素推回优先级队列。
- 重复上述操作,直到优先队列变空。
- 打印op ,作为这个问题的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number
// of operations required to make all
// array elements zero
int setElementstoZero(int arr[], int N)
{
// Create a priority queue
priority_queue pq;
// Variable to store the number
// of operations
int op = 0;
for (int i = 0; i < N; i++) {
if (arr[i] > 0) {
pq.push(arr[i]);
}
}
// Iterate over the priority queue
// till size is greater than 1
while (pq.size() > 1) {
// Increment op by 1
op += 1;
auto p = pq.top();
pq.pop();
auto q = pq.top();
pq.pop();
// If the element is still greater
// than zero again push it again in pq
if (p - q > 0) {
pq.push(p);
}
}
// Return op as the answer
return op;
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 3, 4 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << setElementstoZero(arr, N);
return 0;
}
Java
// Java code for the above approach
import java.util.*;
class CustomComparator implements Comparator {
@Override
public int compare(Integer number1, Integer number2)
{
int value = number1.compareTo(number2);
// elements are sorted in reverse order
if (value > 0) {
return -1;
}
else if (value < 0) {
return 1;
}
else {
return 0;
}
}
}
class GFG
{
// Function to find the minimum number
// of operations required to make all
// array elements zero
static int setElementstoZero(int arr[], int N)
{
// Create a priority queue
PriorityQueue pq
= new PriorityQueue(
new CustomComparator());
// Variable to store the number
// of operations
int op = 0;
for (int i = 0; i < N; i++) {
if (arr[i] > 0) {
pq.add(arr[i]);
}
}
// Iterate over the priority queue
// till size is greater than 1
while (pq.size() > 1)
{
// Increment op by 1
op = op + 1;
Integer p = pq.poll();
Integer q = pq.poll();
// If the element is still greater
// than zero again push it again in pq
if (p - q > 0) {
pq.add(p);
}
}
// Return op as the answer
return op;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 4 };
int N = arr.length;
System.out.println(setElementstoZero(arr, N));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python program for the above approach
# Function to find the minimum number
# of operations required to make all
# array elements zero
def setElementstoZero(arr, N):
# Create a priority queue
pq = []
# Variable to store the number
# of operations
op = 0
for i in range(N):
if (arr[i] > 0):
pq.append(arr[i])
pq.sort()
# Iterate over the priority queue
# till size is greater than 1
while (len(pq) > 1):
# Increment op by 1
op += 1
p = pq[len(pq) - 1]
pq.pop()
q = pq[len(pq)-1]
pq.pop()
# If the element is still greater
# than zero again push it again in pq
if (p - q > 0):
pq.append(p)
pq.sort()
# Return op as the answer
return op
# Driver Code
arr = [1, 2, 3, 4]
N = len(arr)
print(setElementstoZero(arr, N))
# This code is contributed by Saurabh Jaiswal
C#
// C# code for the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find the minimum number
// of operations required to make all
// array elements zero
static int setElementstoZero(int[] arr, int N)
{
// Create a priority queue
List pq = new List();
// Variable to store the number
// of operations
int op = 0;
for (int i = 0; i < N; i++) {
if (arr[i] > 0) {
pq.Add(arr[i]);
}
}
// Iterate over the priority queue
// till size is greater than 1
while (pq.Count > 1) {
pq.Sort();
pq.Reverse();
// Increment op by 1
op = op + 1;
int p = pq[0];
int q = pq[1];
pq.RemoveRange(0, 2);
// If the element is still greater
// than zero again push it again in pq
if (p - q > 0) {
pq.Add(p);
}
}
// Return op as the answer
return op;
}
// Driver Code
public static void Main(String[] args)
{
int[] arr = { 1, 2, 3, 4 };
int N = arr.Length;
Console.WriteLine(setElementstoZero(arr, N));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出
3
时间复杂度: O(NlogN)
辅助空间: O(N)