给定一个正整数K以及分别由[1,K]范围内的M和N个正整数组成的两个数组A []和B [] ,任务是最大程度地减少范围为[[ 1,K],这样两个数组的元素之和变得相等。如果不可能使总和相等,则打印-1 。
例子:
Input: K = 6, A[] = {3, 4, 1}, B[] = {6, 6, 6}
Output: 2
Explanation:
One of the possible way is to replace elements of array B[] at indexes 0 and 1 with 1 in two moves. Therefore, the array B[] modifies to {1, 1, 6}.
Now, the sum of both the arrays is 8, which is equal.
Input: A[] = {4, 3, 2}, B[] = {2, 3, 3, 1}, K = 6, N = 4, M = 3
Output: 1
方法:可以使用两指针技术解决给定的问题。请按照以下步骤解决问题:
- 初始化用于遍历数组的4个变量,例如l1 = 0,r1 = M – 1,l2 = 0,r2 = N – 1 。
- 初始化一个变量,例如res ,以存储所需的最少更换次数。
- 以升序对两个给定的数组进行排序。
- 找到两个数组之和的差,并将其存储在变量diff中。
- 迭代直到l1≤r1或l2≤r2并执行以下步骤:
- 如果diff = 0:跳出循环。
- 如果diff超过0:取(A [r1] – 1)和(K – B [l2])之间的最大值,然后从差diff中减去它,然后递增( l2) ,如果(K – B [l2])的值更伟大。否则,将r1减1 。
- 否则,取(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)