给定一个数组说L = [3,4,6,7,2,1]和一个整数Z = 8,找到2个整数X,Y属于L,使得X + Y = Z
这是一种可能的解决方案 -
public static void findIntegersSum(List<Integer> list, int z) {
for(int i = 0 ;i < list.size(); i++) {
for(int j = i+1 ; j< list.size(); j++) {
if(list.get(i) + list.get(j) == z) {
System.out.println(" X = " + list.get(i) + "\t Y=" + list.get(j));
return;
}
}
}
System.out.println(" No match found !!");
}
问题是 - 我们能否优化上述解决方案?
答案 0 :(得分:2)
您可以使用Set数据类型的实现来执行此操作。 Set通常实现为Hash table(Java中的HashSet)或Binary Search Tree(Java中的TreeSet)。散列表实现通常使用更多内存,但在平均情况下具有恒定时间O(1)查找和插入,树实现使用线性内存,但在平均情况下具有O(log n)查找和插入。
使用此数据结构的伪代码如下:
S = set(L) // Iterate through L and put it in a set, O(n) or O(n log n)
for element in L: // O(n)
if S.has(Z - element): // O(1) or O(log n) depending on HashSet or TreeSet
X = element
Y = Z - element
break
此解决方案是O(n)或O(n log n)而不是O(n ^ 2)。
答案 1 :(得分:2)
如果允许使用O(R)的额外空间,其中R是数字范围,则该方法可以在O(n)时间内求解。这是实现
#include <stdio.h>
#define MAX 100000
void printPairs(int arr[], int arr_size, int sum)
{
int i, temp;
bool binMap[MAX] = {0}; /*initialize hash map as 0*/
for(i = 0; i < arr_size; i++)
{
temp = sum - arr[i];
if(temp >= 0 && binMap[temp] == 1)
{
printf("Pair with given sum %d is (%d, %d) \n", sum, arr[i], temp);
}
binMap[arr[i]] = 1;
}
}
/* Driver program to test above function */
int main()
{
int A[] = {1, 4, 45, 6, 10, 8};
int n = 16;
int arr_size = 6;
printPairs(A, arr_size, n);
getchar();
return 0;
}
答案 2 :(得分:0)
对它进行排序,之后您只需迭代一次数组,并检查匹配值是否在数组中。这对大型阵列来说只会更有效。
答案 3 :(得分:0)
以下解决方案将更加优化,因为它会减少每个步骤的列表大小。
static void findIntegersSum(List<Integer> list, int z) {
for(int i = 0 ;i < list.size(); i++) {
int X = list.remove(i); // Reduce your list
int Y = z - X;
if (list.contains(Y)) {
System.out.println(" X = " + X + "\t Y=" + Y);
return;
}
}
System.out.println(" No match found !!");
}