📌  相关文章
📜  最小化相邻元素上的增减操作以将数组 A 转换为 B

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

给定两个由N 个正整数组成的数组A[]B[] ,任务是找到将数组A[]的相邻数组元素转换为数组B[]所需的最小递增和递减次数。如果不可能,则打印“-1”

例子:

方法:可以使用贪心方法解决给定的问题。以下是步骤:

  • 可以看出,如果数组A[]B[]的总和不相等,则不存在有效的操作序列。在这种情况下,答案将是-1
  • 否则,遍历给定的数组A[]并根据以下情况执行以下步骤:
    1. A[i] > B[i] 的情况:
      • 在这种情况下,跟踪额外的值(即A[i] – B[i] )使用来自[i – 1, 0]的指针j 进行迭代并继续将额外的值添加到索引中,直到A[j] < B[j]直到额外的值耗尽(A[i] – B[i]变为0 )或到达数组的末尾。同样,向右遍历[i + 1, N – 1]并继续添加额外的值。
      • 跟踪变量中的移动次数并将1从索引i转移到索引j ,所需的最小操作次数是|i – j| .
    2. A[i] <= B[i] 的情况。在这种情况下,迭代到i的下一个值,因为在上述情况下迭代时将考虑这些索引。

下面是上述方法的实现:

C++
// C++ Program of the above approach
#include 
using namespace std;
 
// Function to calculate the minimum
// number of operations to convert
// array A to array B by incrementing
// and decrementing adjacent elements
int minimumMoves(int A[], int B[], int N)
{
    // Stores the final count
    int ans = 0;
 
    // Stores the sum of array A
    // and B respectivelly
    int sum_A = 0, sum_B = 0;
    for (int i = 0; i < N; i++) {
        sum_A += A[i];
    }
    for (int i = 0; i < N; i++) {
        sum_B += B[i];
    }
 
    // Check of the sums are unequall
    if (sum_A != sum_B) {
        return -1;
    }
 
    // Pointer to iterate through array
    int i = 0;
 
    while (i < N) {
 
        // Case 1 where A[i] > B[i]
        if (A[i] > B[i]) {
 
            // Stores the extra values
            // for the current index
            int temp = A[i] - B[i];
            int j = i - 1;
 
            // Iterate the array from [i-1, 0]
            while (j >= 0 && temp > 0) {
                if (B[j] > A[j]) {
 
                    // Stores the count of
                    // values being transfered
                    // from A[i] to A[j]
                    int cnt = min(temp, (B[j] - A[j]));
                    A[j] += cnt;
                    temp -= cnt;
 
                    // Add operation count
                    ans += (cnt * abs(j - i));
                }
                j--;
            }
 
            // Iterate the array in right
            // direction id A[i]-B[i] > 0
            if (temp > 0) {
                int j = i + 1;
 
                // Iterate the array from [i+1, n-1]
                while (j < N && temp > 0) {
                    if (B[j] > A[j]) {
 
                        // Stores the count of
                        // values being transfered
                        // from A[i] to A[j]
                        int cnt = min(temp, (B[j] - A[j]));
                        A[j] += cnt;
                        temp -= cnt;
 
                        // Add operation count
                        ans += (cnt * abs(j - i));
                    }
                    j++;
                }
            }
        }
        i++;
    }
 
    // Return Answer
    return ans;
}
 
// Driver Code
int main()
{
    int A[] = { 1, 5, 7 };
    int B[] = { 13, 0, 0 };
    int N = sizeof(A) / sizeof(int);
 
    // Function Call
    cout << minimumMoves(A, B, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
 
class GFG
{
   
    // Function to calculate the minimum
    // number of operations to convert
    // array A to array B by incrementing
    // and decrementing adjacent elements
    static int minimumMoves(int A[], int B[], int N)
    {
       
        // Stores the final count
        int ans = 0;
 
        // Stores the sum of array A
        // and B respectivelly
        int sum_A = 0, sum_B = 0;
        for (int i = 0; i < N; i++) {
            sum_A += A[i];
        }
        for (int i = 0; i < N; i++) {
            sum_B += B[i];
        }
 
        // Check of the sums are unequall
        if (sum_A != sum_B) {
            return -1;
        }
 
        // Pointer to iterate through array
        int i = 0;
 
        while (i < N) {
 
            // Case 1 where A[i] > B[i]
            if (A[i] > B[i]) {
 
                // Stores the extra values
                // for the current index
                int temp = A[i] - B[i];
                int j = i - 1;
 
                // Iterate the array from [i-1, 0]
                while (j >= 0 && temp > 0) {
                    if (B[j] > A[j]) {
 
                        // Stores the count of
                        // values being transfered
                        // from A[i] to A[j]
                        int cnt
                            = Math.min(temp, (B[j] - A[j]));
                        A[j] += cnt;
                        temp -= cnt;
 
                        // Add operation count
                        ans += (cnt * Math.abs(j - i));
                    }
                    j--;
                }
 
                // Iterate the array in right
                // direction id A[i]-B[i] > 0
                if (temp > 0) {
                     j = i + 1;
 
                    // Iterate the array from [i+1, n-1]
                    while (j < N && temp > 0) {
                        if (B[j] > A[j]) {
 
                            // Stores the count of
                            // values being transfered
                            // from A[i] to A[j]
                            int cnt = Math.min(
                                temp, (B[j] - A[j]));
                            A[j] += cnt;
                            temp -= cnt;
 
                            // Add operation count
                            ans += (cnt * Math.abs(j - i));
                        }
                        j++;
                    }
                }
            }
            i++;
        }
 
        // Return Answer
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int A[] = { 1, 5, 7 };
        int B[] = { 13, 0, 0 };
        int N = A.length;
 
        // Function Call
        System.out.println(minimumMoves(A, B, N));
    }
}
 
// This code is contributed by Potta Lokesh


C#
// C# program for the above approach
 
using System;
 
 
public class GFG
{
   
    // Function to calculate the minimum
    // number of operations to convert
    // array A to array B by incrementing
    // and decrementing adjacent elements
    static int minimumMoves(int []A, int []B, int N)
    {
       
        // Stores the final count
        int ans = 0;
 
        // Stores the sum of array A
        // and B respectivelly
        int sum_A = 0, sum_B = 0;
        for (int i = 0; i < N; i++) {
            sum_A += A[i];
        }
        for (int i = 0; i < N; i++) {
            sum_B += B[i];
        }
 
        // Check of the sums are unequall
        if (sum_A != sum_B) {
            return -1;
        }
 
        // Pointer to iterate through array
        int k = 0;
 
        while (k < N) {
 
            // Case 1 where A[i] > B[i]
            if (A[k] > B[k]) {
 
                // Stores the extra values
                // for the current index
                int temp = A[k] - B[k];
                int j = k - 1;
 
                // Iterate the array from [i-1, 0]
                while (j >= 0 && temp > 0) {
                    if (B[j] > A[j]) {
 
                        // Stores the count of
                        // values being transfered
                        // from A[i] to A[j]
                        int cnt
                            = Math.Min(temp, (B[j] - A[j]));
                        A[j] += cnt;
                        temp -= cnt;
 
                        // Add operation count
                        ans += (cnt * Math.Abs(j - k));
                    }
                    j--;
                }
 
                // Iterate the array in right
                // direction id A[i]-B[i] > 0
                if (temp > 0) {
                     j = k + 1;
 
                    // Iterate the array from [i+1, n-1]
                    while (j < N && temp > 0) {
                        if (B[j] > A[j]) {
 
                            // Stores the count of
                            // values being transfered
                            // from A[i] to A[j]
                            int cnt = Math.Min(
                                temp, (B[j] - A[j]));
                            A[j] += cnt;
                            temp -= cnt;
 
                            // Add operation count
                            ans += (cnt * Math.Abs(j - k));
                        }
                        j++;
                    }
                }
            }
            k++;
        }
 
        // Return Answer
        return ans;
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        int []A = { 1, 5, 7 };
        int []B = { 13, 0, 0 };
        int N = A.Length;
 
        // Function Call
        Console.WriteLine(minimumMoves(A, B, N));
    }
}
 
// This code is contributed by AnkThon


输出:
19

时间复杂度: O(N 2 )
辅助空间: O(1)

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