给定一个不同整数的数组,找出是否有两对 (a, b) 和 (c, d) 使得 a+b = c+d,并且 a、b、c 和 d 是不同的元素。如果有多个答案,则打印其中任何一个。
例子:
Input: {3, 4, 7, 1, 2, 9, 8}
Output: (3, 8) and (4, 7)
Explanation: 3+8 = 4+7
Input: {3, 4, 7, 1, 12, 9};
Output: (4, 12) and (7, 9)
Explanation: 4+12 = 7+9
Input: {65, 30, 7, 90, 1, 9, 8};
Output: No pairs found
预期时间复杂度: O(n 2 )
一个简单的解决方案是运行四个循环来生成数组元素的所有可能的四元组。对于每个四元组 (a, b, c, d),检查是否 (a+b) = (c+d)。该解决方案的时间复杂度为 O(n 4 )。
一个有效的解决方案可以在 O(n 2 ) 时间内解决这个问题。这个想法是使用散列。我们使用 sum 作为键,pair 作为哈希表中的值。
Loop i = 0 to n-1 :
Loop j = i + 1 to n-1 :
calculate sum
If in hash table any index already exist
Then print (i, j) and previous pair
from hash table
Else update hash table
EndLoop;
EndLoop;
下面是上述想法的实现。在下面的实现中,使用映射而不是哈希。 map插入和搜索的时间复杂度实际上是O(Log n)而不是O(1)。所以下面的实现是 O(n 2 Log n)。
C++
// Find four different elements a,b,c and d of array such that
// a+b = c+d
#include
using namespace std;
bool findPairs(int arr[], int n)
{
// Create an empty Hash to store mapping from sum to
// pair indexes
map > Hash;
// Traverse through all possible pairs of arr[]
for (int i = 0; i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
{
// If sum of current pair is not in hash,
// then store it and continue to next pair
int sum = arr[i] + arr[j];
if (Hash.find(sum) == Hash.end())
Hash[sum] = make_pair(i, j);
else // Else (Sum already present in hash)
{
// Find previous pair
pair pp = Hash[sum];// pp->previous pair
// Since array elements are distinct, we don't
// need to check if any element is common among pairs
cout << "(" << arr[pp.first] << ", " << arr[pp.second]
<< ") and (" << arr[i] << ", " << arr[j] << ")n";
return true;
}
}
}
cout << "No pairs found";
return false;
}
// Driver program
int main()
{
int arr[] = {3, 4, 7, 1, 2, 9, 8};
int n = sizeof arr / sizeof arr[0];
findPairs(arr, n);
return 0;
}
Java
// Java Program to find four different elements a,b,c and d of
// array such that a+b = c+d
import java.io.*;
import java.util.*;
class ArrayElements
{
// Class to represent a pair
class pair
{
int first, second;
pair(int f,int s)
{
first = f; second = s;
}
};
boolean findPairs(int arr[])
{
// Create an empty Hash to store mapping from sum to
// pair indexes
HashMap map = new HashMap();
int n=arr.length;
// Traverse through all possible pairs of arr[]
for (int i=0; i
Python3
# Python Program to find four different elements a,b,c and d of
# array such that a+b = c+d
# function to find a, b, c, d such that
# (a + b) = (c + d)
def find_pair_of_sum(arr: list, n: int):
map = {}
for i in range(n):
for j in range(i+1, n):
sum = arr[i] + arr[j]
if sum in map:
print(f"{map[sum]} and ({arr[i]}, {arr[j]})")
return
else:
map[sum] = (arr[i], arr[j])
# Driver code
if __name__ == "__main__":
arr = [3, 4, 7, 1, 2, 9, 8]
n = len(arr)
find_pair_of_sum(arr, n)
C#
using System;
using System.Collections.Generic;
// C# Program to find four different elements a,b,c and d of
// array such that a+b = c+d
public class ArrayElements
{
// Class to represent a pair
public class pair
{
private readonly ArrayElements outerInstance;
public int first, second;
public pair(ArrayElements outerInstance, int f, int s)
{
this.outerInstance = outerInstance;
first = f;
second = s;
}
}
public virtual bool findPairs(int[] arr)
{
// Create an empty Hash to store mapping from sum to
// pair indexes
Dictionary map = new Dictionary();
int n = arr.Length;
// Traverse through all possible pairs of arr[]
for (int i = 0; i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
{
// If sum of current pair is not in hash,
// then store it and continue to next pair
int sum = arr[i] + arr[j];
if (!map.ContainsKey(sum))
{
map[sum] = new pair(this, i,j);
}
else // Else (Sum already present in hash)
{
// Find previous pair
pair p = map[sum];
// Since array elements are distinct, we don't
// need to check if any element is common among pairs
Console.WriteLine("(" + arr[p.first] + ", " + arr[p.second] + ") and (" + arr[i] + ", " + arr[j] + ")");
return true;
}
}
}
return false;
}
// Testing program
public static void Main(string[] args)
{
int[] arr = new int[] {3, 4, 7, 1, 2, 9, 8};
ArrayElements a = new ArrayElements();
a.findPairs(arr);
}
}
// This code is contributed by Shrikant13
Javascript
输出:
(3, 8) and (4, 7)
感谢 Gaurav Ahirwar 提出上述解决方案。
锻炼:
1)使用数组中允许的重复项扩展上述解决方案。
2)进一步扩展解决方案以在输出中打印所有四元组而不是一个。并且所有四元组都应按字典顺序打印(较小的值在较大的值之前)。假设我们有两个解 S1 和 S2。
S1 : a1 b1 c1 d1 ( these are values of indices int the array )
S2 : a2 b2 c2 d2
S1 is lexicographically smaller than S2 iff
a1 < a2 OR
a1 = a2 AND b1 < b2 OR
a1 = a2 AND b1 = b2 AND c1 < c2 OR
a1 = a2 AND b1 = b2 AND c1 = c2 AND d1 < d2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。