📌  相关文章
📜  最小化值最大为K的替换,以使两个给定数组的总和相等

📅  最后修改于: 2021-04-17 14:36:54             🧑  作者: Mango

给定一个正整数K以及分别由[1,K]范围内的MN个正整数组成的两个数组A []B [] ,任务是最大程度地减少范围为[[ 1,K],这样两个数组的元素之和变得相等。如果不可能使总和相等,则打印-1

例子:

方法:可以使用两指针技术解决给定的问题。请按照以下步骤解决问题:

  • 初始化用于遍历数组的4个变量,例如l1 = 0,r1 = M – 1,l2 = 0,r2 = N – 1
  • 初始化一个变量,例如res ,以存储所需的最少更换次数。
  • 以升序对两个给定的数组进行排序。
  • 找到两个数组之和的差,并将其存储在变量diff中
  • 迭代直到l1≤r1l2≤r2并执行以下步骤:
    • 如果diff = 0:跳出循环。
    • 如果diff超过0:(A [r1] – 1)(K – B [l2])之间的最大值,然后从差diff中减去它,然后递增( l2) ,如果(K – B [l2])的值更伟大。否则,将r11
    • 否则,取(B [r2] – 1)(K – A [l1])之间的最大值,并将其与差值diff相加,如果(K – A [l1])较大,则增加l1 。否则,将r2的值减1
    • res的值增加1
  • 完成上述步骤后,将res的值打印为所需的最少阵列元素替换次数。

下面是上述方法的实现:

C++
#include 
using namespace std;
 
// Functon to find minimum number
// of replacements required to make
// the sum of two arrays equal
int makeSumEqual(vector a, vector b,
                 int K, int M, int N)
{
 
  // Stores the sum of a[]
  int sum1 = 0;
 
  // Stores the sum of b[]
  int sum2 = 0;
 
  // Calculate sum of the array a[]
  for (int el : a)
    sum1 += el;
 
  // Calculate sum of the array b[]
  for (int el : b)
    sum2 += el;
 
  // Stores the difference
  // between a[] and b[]
  int diff = sum1 - sum2;
 
  // Left and Right pointer
  // to traverse the array a[]
  int l1 = 0, r1 = M - 1;
 
  // Left and Right pointer
  // to traverse the array b[]
  int l2 = 0, r2 = N - 1;
 
  // Stores the count of moves
  int res = 0;
 
  // Sort the arrays in
  // ascending order
  sort(a.begin(),a.end());
  sort(b.begin(),b.end());
 
  // Iterate while diff != 0 and
  // l1 <= r1 or l2 <= r2
  while (l1 <= r1 || l2 <= r2)
  {
    if (diff == 0)
    {
      break;
    }
 
    // If diff is greater than 0
    if (diff > 0)
    {
 
      // If all pointers are valid
      if (l2 <= r2 && l1 <= r1)
      {
 
        if (K - b[l2] < a[r1] - 1) {
 
          int sub = min(
            a[r1] - 1, diff);
          diff -= sub;
          a[r1] -= sub;
          r1--;
        }
        else {
 
          int sub = min(
            K - b[l2], diff);
          diff -= sub;
          b[l2] += sub;
          l2++;
        }
      }
 
      // Otherwise, if only pointers
      // of array a[] is valid
      else if (l1 <= r1) {
 
        int sub = min(
          a[r1] - 1, diff);
        diff -= sub;
        a[r1] -= sub;
        r1--;
      }
 
      // Otherwise
      else {
 
        int sub = min(
          K - b[l2], diff);
        diff -= sub;
        b[l2] += sub;
        l2++;
      }
    }
 
    // If diff is less than 0
    else {
 
      // If all pointers are valid
      if (l1 <= r1 && l2 <= r2) {
        if (K - a[l1]
            < b[r2] - 1) {
 
          int sub = min(
            b[r2] - 1,
            -1 * diff);
          diff += sub;
          b[r2] -= sub;
          r2--;
        }
 
        else {
 
          int sub = min(
            K - a[l1],
            -1 * diff);
          diff += sub;
          a[l1] -= sub;
          l1++;
        }
      }
 
      // Otherwise, if only pointers
      // of array a[] is valid
      else if (l2 <= r2) {
 
        int sub
          = min(
          b[r2] - 1,
          -1 * diff);
        diff += sub;
        b[r2] -= sub;
        r2--;
      }
 
      // Otherwise
      else {
 
        int sub = min(
          K - a[l1], diff);
        diff += sub;
        a[l1] += sub;
        l1++;
      }
    }
 
    // Increment count
    // of res by one
    res++;
  }
 
  // If diff is 0, then return res
  if (diff == 0)
    return res;
 
  // Otherwise, return -1
  else
    return -1;
}
 
// Driver Code
int main()
{
  vector A = { 1, 4, 3 };
  vector B = { 6, 6, 6 };
  int M = A.size();
  int N = B.size();
  int K = 6;
 
  cout << makeSumEqual(A, B, K,M, N);
 
  return 0;
}
 
// This code is contributed by mohit kumar 29.


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Functon to find minimum number
    // of replacements required to make
    // the sum of two arrays equal
    public static int makeSumEqual(
        int[] a, int[] b, int K,
        int M, int N)
    {
        // Stores the sum of a[]
        int sum1 = 0;
 
        // Stores the sum of b[]
        int sum2 = 0;
 
        // Calculate sum of the array a[]
        for (int el : a)
            sum1 += el;
 
        // Calculate sum of the array b[]
        for (int el : b)
            sum2 += el;
 
        // Stores the difference
        // between a[] and b[]
        int diff = sum1 - sum2;
 
        // Left and Right pointer
        // to traverse the array a[]
        int l1 = 0, r1 = M - 1;
 
        // Left and Right pointer
        // to traverse the array b[]
        int l2 = 0, r2 = N - 1;
 
        // Stores the count of moves
        int res = 0;
 
        // Sort the arrays in
        // ascending order
        Arrays.sort(a);
        Arrays.sort(b);
 
        // Iterate while diff != 0 and
        // l1 <= r1 or l2 <= r2
        while (l1 <= r1 || l2 <= r2) {
            if (diff == 0) {
 
                break;
            }
 
            // If diff is greater than 0
            if (diff > 0) {
 
                // If all pointers are valid
                if (l2 <= r2 && l1 <= r1) {
 
                    if (K - b[l2] < a[r1] - 1) {
 
                        int sub = Math.min(
                            a[r1] - 1, diff);
                        diff -= sub;
                        a[r1] -= sub;
                        r1--;
                    }
                    else {
 
                        int sub = Math.min(
                            K - b[l2], diff);
                        diff -= sub;
                        b[l2] += sub;
                        l2++;
                    }
                }
 
                // Otherwise, if only pointers
                // of array a[] is valid
                else if (l1 <= r1) {
 
                    int sub = Math.min(
                        a[r1] - 1, diff);
                    diff -= sub;
                    a[r1] -= sub;
                    r1--;
                }
 
                // Otherwise
                else {
 
                    int sub = Math.min(
                        K - b[l2], diff);
                    diff -= sub;
                    b[l2] += sub;
                    l2++;
                }
            }
 
            // If diff is less than 0
            else {
 
                // If all pointers are valid
                if (l1 <= r1 && l2 <= r2) {
                    if (K - a[l1]
                        < b[r2] - 1) {
 
                        int sub = Math.min(
                            b[r2] - 1,
                            -1 * diff);
                        diff += sub;
                        b[r2] -= sub;
                        r2--;
                    }
 
                    else {
 
                        int sub = Math.min(
                            K - a[l1],
                            -1 * diff);
                        diff += sub;
                        a[l1] -= sub;
                        l1++;
                    }
                }
 
                // Otherwise, if only pointers
                // of array a[] is valid
                else if (l2 <= r2) {
 
                    int sub
                        = Math.min(
                            b[r2] - 1,
                            -1 * diff);
                    diff += sub;
                    b[r2] -= sub;
                    r2--;
                }
 
                // Otherwise
                else {
 
                    int sub = Math.min(
                        K - a[l1], diff);
                    diff += sub;
                    a[l1] += sub;
                    l1++;
                }
            }
 
            // Increment count
            // of res by one
            res++;
        }
 
        // If diff is 0, then return res
        if (diff == 0)
            return res;
 
        // Otherwise, return -1
        else
            return -1;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] A = { 1, 4, 3 };
        int[] B = { 6, 6, 6 };
        int M = A.length;
        int N = B.length;
        int K = 6;
 
        System.out.println(
            makeSumEqual(A, B, K,
                         M, N));
    }
}


C#
// C# program to implement
// the above approach
using System;
 
public class GFG
{
   
    // Functon to find minimum number
    // of replacements required to make
    // the sum of two arrays equal
    public static int makeSumEqual(
        int[] a, int[] b, int K,
        int M, int N)
    {
       
        // Stores the sum of a[]
        int sum1 = 0;
 
        // Stores the sum of b[]
        int sum2 = 0;
 
        // Calculate sum of the array a[]
        foreach (int el in a)
            sum1 += el;
 
        // Calculate sum of the array b[]
        foreach (int el in b)
            sum2 += el;
 
        // Stores the difference
        // between a[] and b[]
        int diff = sum1 - sum2;
 
        // Left and Right pointer
        // to traverse the array a[]
        int l1 = 0, r1 = M - 1;
 
        // Left and Right pointer
        // to traverse the array b[]
        int l2 = 0, r2 = N - 1;
 
        // Stores the count of moves
        int res = 0;
 
        // Sort the arrays in
        // ascending order
        Array.Sort(a);
        Array.Sort(b);
 
        // Iterate while diff != 0 and
        // l1 <= r1 or l2 <= r2
        while (l1 <= r1 || l2 <= r2) {
            if (diff == 0) {
 
                break;
            }
 
            // If diff is greater than 0
            if (diff > 0) {
 
                // If all pointers are valid
                if (l2 <= r2 && l1 <= r1) {
 
                    if (K - b[l2] < a[r1] - 1) {
 
                        int sub = Math.Min(
                            a[r1] - 1, diff);
                        diff -= sub;
                        a[r1] -= sub;
                        r1--;
                    }
                    else {
 
                        int sub = Math.Min(
                            K - b[l2], diff);
                        diff -= sub;
                        b[l2] += sub;
                        l2++;
                    }
                }
 
                // Otherwise, if only pointers
                // of array a[] is valid
                else if (l1 <= r1) {
 
                    int sub = Math.Min(
                        a[r1] - 1, diff);
                    diff -= sub;
                    a[r1] -= sub;
                    r1--;
                }
 
                // Otherwise
                else {
 
                    int sub = Math.Min(
                        K - b[l2], diff);
                    diff -= sub;
                    b[l2] += sub;
                    l2++;
                }
            }
 
            // If diff is less than 0
            else {
 
                // If all pointers are valid
                if (l1 <= r1 && l2 <= r2) {
                    if (K - a[l1]
                        < b[r2] - 1) {
 
                        int sub = Math.Min(
                            b[r2] - 1,
                            -1 * diff);
                        diff += sub;
                        b[r2] -= sub;
                        r2--;
                    }
 
                    else {
 
                        int sub = Math.Min(
                            K - a[l1],
                            -1 * diff);
                        diff += sub;
                        a[l1] -= sub;
                        l1++;
                    }
                }
 
                // Otherwise, if only pointers
                // of array a[] is valid
                else if (l2 <= r2) {
 
                    int sub
                        = Math.Min(
                            b[r2] - 1,
                            -1 * diff);
                    diff += sub;
                    b[r2] -= sub;
                    r2--;
                }
 
                // Otherwise
                else {
 
                    int sub = Math.Min(
                        K - a[l1], diff);
                    diff += sub;
                    a[l1] += sub;
                    l1++;
                }
            }
 
            // Increment count
            // of res by one
            res++;
        }
 
        // If diff is 0, then return res
        if (diff == 0)
            return res;
 
        // Otherwise, return -1
        else
            return -1;
    }
 
// Driver Code
public static void Main(String[] args)
{
    int[] A = { 1, 4, 3 };
        int[] B = { 6, 6, 6 };
        int M = A.Length;
        int N = B.Length;
        int K = 6;
 
        Console.WriteLine(
            makeSumEqual(A, B, K,
                         M, N));
}
}


输出:
2

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