📌  相关文章
📜  最小增量/减量使数组不递增

📅  最后修改于: 2021-04-24 15:05:35             🧑  作者: Mango

给定一个数组a,您的任务是将其转换为非递增形式,以便我们可以将数组值以1的最小增量递增或递减。

例子 :

Input : a[] = {3, 1, 2, 1}
Output : 1
Explanation :
We can convert the array into 3 1 1 1 by
changing 3rd element of array i.e. 2 
into its previous integer 1 in one step
hence only one step is required.

Input : a[] = {3, 1, 5, 1}
Output : 4
We need to decrease 5 to 1 to make array sorted
in non-increasing order.

Input : a[] = {1, 5, 5, 5}
Output : 4
We need to increase 1 to 5.

蛮力方法:我们考虑每个元素的两种可能性,并找到至少两种可能性。

高效方法:计算最终数组元素和当前数组元素之间的绝对差之和。因此,答案将是第ith个元素和直到那时为止出现的最小元素之间的差之和。为此,我们可以维持最小堆,以找到到那时为止遇到的最小元素。在最小优先级队列中,我们将把元素和新元素与先前的最小值进行比较。如果找到了新的最小值,我们将对其进行更新,因为即将到来的下一个元素中的每个元素都应小于到目前为止找到的当前最小元素。在这里,我们计算差值,以便我们可以得到多少数量的更改,以便当前数字等于或小于之前遇到的数字。最后,所有这些差异的总和将是我们的答案,因为这将给我们最终的价值,我们必须改变这些要素。

下面是上述方法的实现:

C++
// CPP code to count the change required to
// convert the array into non-increasing array
#include 
using namespace std;
 
int DecreasingArray(int a[], int n)
{
    int sum = 0, dif = 0;
 
    // min heap
    priority_queue, greater > pq;
 
    // Here in the loop we will
    // check that whether the upcoming
    // element of array is less than top
    // of priority queue. If yes then we
    // calculate the difference. After
    // that we will remove that element
    // and push the current element in
    // queue. And the sum is incremented
    // by the value of difference
    for (int i = 0; i < n; i++) {
        if (!pq.empty() && pq.top() < a[i]) {
            dif = a[i] - pq.top();
            sum += dif;
            pq.pop();
        }
        pq.push(a[i]);
    }
 
    return sum;
}
 
// Driver Code
int main()
{
    int a[] = { 3, 1, 2, 1 };
    int n = sizeof(a) / sizeof(a[0]);
 
    cout << DecreasingArray(a, n);
 
    return 0;
}


Java
// Java code to count the change required to
// convert the array into non-increasing array
import java.util.PriorityQueue;
 
class GFG
{
    public static int DecreasingArray(int a[], int n)
    {
        int sum = 0, dif = 0;
 
        PriorityQueue pq = new PriorityQueue<>();
 
        // Here in the loop we will
        // check that whether the upcoming
        // element of array is less than top
        // of priority queue. If yes then we
        // calculate the difference. After
        // that we will remove that element
        // and push the current element in
        // queue. And the sum is incremented
        // by the value of difference
        for (int i = 0; i < n; i++)
        {
            if (!pq.isEmpty() && pq.element() < a[i])
            {
                dif = a[i] - pq.element();
                sum += dif;
                pq.remove();
            }
            pq.add(a[i]);
        }
     
    return sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
         
        int[] a = {3, 1, 2, 1};
         
        int n = a.length;
 
        System.out.println(DecreasingArray(a, n));
    }
}
 
// This Code is contributed by sanjeev2552


Python3
# Python3 code to count the change required to
# convert the array into non-increasing array
from queue import PriorityQueue
 
def DecreasingArray(a, n):
     
    ss, dif = (0,0)
     
    # min heap
    pq = PriorityQueue()
 
    # Here in the loop we will
    # check that whether the upcoming
    # element of array is less than top
    # of priority queue. If yes then we
    # calculate the difference. After
    # that we will remove that element
    # and push the current element in
    # queue. And the sum is incremented
    # by the value of difference
    for i in range(n):
        tmp = 0
         
        if not pq.empty():
            tmp = pq.get()
            pq.put(tmp)
         
        if not pq.empty() and tmp < a[i]:
            dif = a[i] - tmp
            ss += dif
            pq.get()
         
        pq.put(a[i])
       
    return ss
     
# Driver code   
if __name__=="__main__":
     
    a = [ 3, 1, 2, 1 ]
    n = len(a)
  
    print(DecreasingArray(a, n))
     
# This code is contributed by rutvik_56


C#
// C# code to count the change required to
// convert the array into non-increasing array
using System;
using System.Collections.Generic;
class GFG
{
    static int DecreasingArray(int[] a, int n)
    {
        int sum = 0, dif = 0;
      
        // min heap
        List pq = new List();
      
        // Here in the loop we will
        // check that whether the upcoming
        // element of array is less than top
        // of priority queue. If yes then we
        // calculate the difference. After
        // that we will remove that element
        // and push the current element in
        // queue. And the sum is incremented
        // by the value of difference
        for (int i = 0; i < n; i++)
        {
            if (pq.Count > 0 && pq[0] < a[i])
            {
                dif = a[i] - pq[0];
                sum += dif;
                pq.RemoveAt(0);
            }
            pq.Add(a[i]);
            pq.Sort();
        }
      
        return sum;
    }  
 
  // Driver code
  static void Main()
  {
    int[] a = { 3, 1, 2, 1 };
    int n = a.Length;
  
    Console.Write(DecreasingArray(a, n));
  }
}
 
// This code is contributed by divyeshrabadiya07.


输出:
1

时间复杂度:O(n log(n))
空间复杂度: O(n)
另请参见:转换为具有最小更改的严格增加的数组。