📌  相关文章
📜  添加数组的元素,直到每个元素都大于或等于 k

📅  最后修改于: 2021-10-28 02:03:08             🧑  作者: Mango

给定一个包含N 个未排序元素的列表,我们需要找到可以添加列表元素以使所有元素大于或等于K 的最小步骤数。我们可以将两个元素加在一起并使它们合二为一。
例子:

Input : arr[] = {1 10 12 9 2 3}
          K = 6
Output : 2
First we add (1 + 2), now the new list becomes 
3 10 12 9 3, then we add (3 + 3),  now the new 
list becomes 6 10 12 9, Now all the elements in 
the list are greater than 6. Hence the output is 
2 i:e 2 operations are required 
to do this.

从上面的解释中可以看出,我们需要提取两个最小的元素,然后将它们的总和添加到列表中。我们需要继续这一步,直到所有元素都大于或等于 K。
方法一(蛮力):
我们可以创建一个简单的数组对其进行排序,然后添加两个最小元素并继续将它们存储在数组中,直到所有元素都大于K
方法二(高效):
如果我们仔细观察,我们会注意到这个问题类似于霍夫曼编码。我们使用最小堆作为这里的主要操作是提取最小和插入。这两个操作都可以在 O(Log n) 时间内完成。

C++
// A C++ program to count minimum steps to make all
// elements greater than or equal to k.
#include
using namespace std;
 
// A class for Min Heap
class MinHeap
{
    int *harr;
    int capacity; // maximum size
    int heap_size; // Current count
public:
    // Constructor
    MinHeap(int *arr, int capacity);
 
    // to heapify a subtree with root at
    // given index
    void heapify(int );
 
    int parent(int i)
    {
        return (i-1)/2;
    }
 
    // to get index of left child of
    // node at index i
    int left(int i)
    {
        return (2*i + 1);
    }
 
    // to get index of right child of
    // node at index i
    int right(int i)
    {
        return (2*i + 2);
    }
 
    // to extract the root which is the
    // minimum element
    int extractMin();
 
    // Returns the minimum key (key at
    // root) from min heap
    int getMin()
    {
        return harr[0];
    }
 
    int getSize()
    {
        return heap_size;
    }
 
    // Inserts a new key 'k'
    void insertKey(int k);
};
 
// Constructor: Builds a heap from
// a given array a[] of given size
MinHeap::MinHeap(int arr[], int n)
{
    heap_size = n;
    capacity = n;
    harr = new int[n];
 
    for (int i=0; i=0; i--)
        heapify(i);
}
 
// Inserts a new key 'k'
void MinHeap::insertKey(int k)
{
    // First insert the new key at the end
    heap_size++;
    int i = heap_size - 1;
    harr[i] = k;
 
    // Fix the min heap property if it is violated
    while (i != 0 && harr[parent(i)] > harr[i])
    {
        swap(harr[i], harr[parent(i)]);
        i = parent(i);
    }
}
 
// Method to remove minimum element
// (or root) from min heap
int MinHeap::extractMin()
{
    if (heap_size <= 0)
        return INT_MAX;
    if (heap_size == 1)
    {
        heap_size--;
        return harr[0];
    }
 
    // Store the minimum value, and
    // remove it from heap
    int root = harr[0];
    harr[0] = harr[heap_size-1];
    heap_size--;
    heapify(0);
 
    return root;
}
 
// A recursive method to heapify a subtree
// with root at given index. This method
// assumes that the subtrees are already
// heapified
void MinHeap::heapify(int i)
{
    int l = left(i);
    int r = right(i);
    int smallest = i;
    if (l < heap_size && harr[l] < harr[i])
        smallest = l;
    if (r < heap_size && harr[r] < harr[smallest])
        smallest = r;
    if (smallest != i)
    {
        swap(harr[i], harr[smallest]);
        heapify(smallest);
    }
}
 
// Returns count of steps needed to make
// all elements greater than or equal to
// k by adding elements
int countMinOps(int arr[], int n, int k)
{
    // Build a min heap of array elements
    MinHeap h(arr, n);
 
    long int res = 0;
 
    while (h.getMin() < k)
    {
        if (h.getSize() == 1)
            return -1;
 
        // Extract two minimum elements
        // and insert their sum
        int first = h.extractMin();
        int second = h.extractMin();
        h.insertKey(first + second);
 
        res++;
    }
 
    return res;
}
 
// Driver code
int main()
{
    int arr[] = {1, 10, 12, 9, 2, 3};
    int n  = sizeof(arr)/sizeof(arr[0]);
    int k = 6;
    cout << countMinOps(arr, n, k);
    return 0;
}


Java
// A Java program to count minimum steps to make all
// elements greater than or equal to k.
public class Add_Elements {
      
    // A class for Min Heap
    static class MinHeap
    {
        int[] harr;
        int capacity; // maximum size
        int heap_size; // Current count
     
        // Constructor: Builds a heap from
        // a given array a[] of given size
        MinHeap(int arr[], int n)
        {
            heap_size = n;
            capacity = n;
            harr = new int[n];
          
            for (int i=0; i=0; i--)
                heapify(i);
        }
      
        // A recursive method to heapify a subtree
        // with root at given index. This method
        // assumes that the subtrees are already
        // heapified
        void heapify(int i)
        {
            int l = left(i);
            int r = right(i);
            int smallest = i;
            if (l < heap_size && harr[l] < harr[i])
                smallest = l;
            if (r < heap_size && harr[r] < harr[smallest])
                smallest = r;
            if (smallest != i)
            {
                int temp = harr[i];
                harr[i] = harr[smallest];
                harr[smallest] = temp;
                heapify(smallest);
            }
        }
      
        static int parent(int i)
        {
            return (i-1)/2;
        }
      
        // to get index of left child of
        // node at index i
        static int left(int i)
        {
            return (2*i + 1);
        }
      
        // to get index of right child of
        // node at index i
        int right(int i)
        {
            return (2*i + 2);
        }
      
        // Method to remove minimum element
        // (or root) from min heap
        int extractMin()
        {
            if (heap_size <= 0)
                return Integer.MAX_VALUE;
            if (heap_size == 1)
            {
                heap_size--;
                return harr[0];
            }
          
            // Store the minimum value, and
            // remove it from heap
            int root = harr[0];
            harr[0] = harr[heap_size-1];
            heap_size--;
            heapify(0);
          
            return root;
        }
      
        // Returns the minimum key (key at
        // root) from min heap
        int getMin()
        {
            return harr[0];
        }
      
        int getSize()
        {
            return heap_size;
        }
      
        // Inserts a new key 'k'
        void insertKey(int k)
        {
            // First insert the new key at the end
            heap_size++;
            int i = heap_size - 1;
            harr[i] = k;
          
            // Fix the min heap property if it is violated
            while (i != 0 && harr[parent(i)] > harr[i])
            {
                 int temp = harr[i];
                 harr[i] = harr[parent(i)];
                 harr[parent(i)] = temp;
                 i = parent(i);
            }
        }
    }
      
      
    // Returns count of steps needed to make
    // all elements greater than or equal to
    // k by adding elements
    static int countMinOps(int arr[], int n, int k)
    {
        // Build a min heap of array elements
        MinHeap h = new MinHeap(arr, n);
      
        int res = 0;
      
        while (h.getMin() < k)
        {
            if (h.getSize() == 1)
                return -1;
      
            // Extract two minimum elements
            // and insert their sum
            int first = h.extractMin();
            int second = h.extractMin();
            h.insertKey(first + second);
      
            res++;
        }
      
        return res;
    }
      
    // Driver code
    public static void main(String args[])
    {
        int arr[] = {1, 10, 12, 9, 2, 3};
        int n  = arr.length;
        int k = 6;
        System.out.println(countMinOps(arr, n, k));
    }
}
// This code is contributed by Sumit Ghosh


C#
// A C# program to count minimum steps to make all
// elements greater than or equal to k.
using System;
     
public class Add_Elements
{
     
    // A class for Min Heap
    public class MinHeap
    {
        public int[] harr;
        public int capacity; // maximum size
        public int heap_size; // Current count
     
        // Constructor: Builds a heap from
        // a given array a[] of given size
        public MinHeap(int []arr, int n)
        {
            heap_size = n;
            capacity = n;
            harr = new int[n];
         
            for (int i = 0; i < n; i++)
                harr[i] = arr[i];
         
            // building the heap from first
            // non-leaf node by calling max
            // heapify function
            for (int i = n/2-1; i >= 0; i--)
                heapify(i);
        }
     
        // A recursive method to heapify a subtree
        // with root at given index. This method
        // assumes that the subtrees are already
        // heapified
        public void heapify(int i)
        {
            int l = left(i);
            int r = right(i);
            int smallest = i;
            if (l < heap_size && harr[l] < harr[i])
                smallest = l;
            if (r < heap_size && harr[r] < harr[smallest])
                smallest = r;
            if (smallest != i)
            {
                int temp = harr[i];
                harr[i] = harr[smallest];
                harr[smallest] = temp;
                heapify(smallest);
            }
        }
     
        public static int parent(int i)
        {
            return (i-1)/2;
        }
     
        // to get index of left child of
        // node at index i
        static int left(int i)
        {
            return (2*i + 1);
        }
     
        // to get index of right child of
        // node at index i
        public int right(int i)
        {
            return (2*i + 2);
        }
     
        // Method to remove minimum element
        // (or root) from min heap
        public int extractMin()
        {
            if (heap_size <= 0)
                return int.MaxValue;
            if (heap_size == 1)
            {
                heap_size--;
                return harr[0];
            }
         
            // Store the minimum value, and
            // remove it from heap
            int root = harr[0];
            harr[0] = harr[heap_size-1];
            heap_size--;
            heapify(0);
         
            return root;
        }
     
        // Returns the minimum key (key at
        // root) from min heap
        public int getMin()
        {
            return harr[0];
        }
     
        public int getSize()
        {
            return heap_size;
        }
     
        // Inserts a new key 'k'
        public void insertKey(int k)
        {
            // First insert the new key at the end
            heap_size++;
            int i = heap_size - 1;
            harr[i] = k;
         
            // Fix the min heap property if it is violated
            while (i != 0 && harr[parent(i)] > harr[i])
            {
                int temp = harr[i];
                harr[i] = harr[parent(i)];
                harr[parent(i)] = temp;
                i = parent(i);
            }
        }
    }
     
     
    // Returns count of steps needed to make
    // all elements greater than or equal to
    // k by adding elements
    static int countMinOps(int []arr, int n, int k)
    {
        // Build a min heap of array elements
        MinHeap h = new MinHeap(arr, n);
     
        int res = 0;
     
        while (h.getMin() < k)
        {
            if (h.getSize() == 1)
                return -1;
     
            // Extract two minimum elements
            // and insert their sum
            int first = h.extractMin();
            int second = h.extractMin();
            h.insertKey(first + second);
     
            res++;
        }
     
        return res;
    }
     
    // Driver code
    public static void Main(String []args)
    {
        int []arr = {1, 10, 12, 9, 2, 3};
        int n = arr.Length;
        int k = 6;
        Console.WriteLine(countMinOps(arr, n, k));
    }
}
 
// This code has been contributed by 29AjayKumar


Javascript


输出:

2

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程