我正在尝试解决一个非常有趣的编程挑战,而且我有点想法为什么我的代码失败了。这是:
编写一个函数,给定一个列表和一个目标总和,返回 任何两个不同元素的从零开始的索引,其总和等于 目标总和。如果没有这样的元素,函数应该 返回null。 例如,findTwoSum(new int [] {1,3,5,7,9},12)应返回以下任何索引元组:
1, 4 (3 + 9 = 12) 2, 3 (5 + 7 = 12) 3, 2 (7 + 5 = 12) 4, 1 (9 + 3 = 12)
应该简单吧?所以这是我的功能:
public static int[] findTwoSum(int[] list, int sum) {
int[] indices = null;
for(int i = 0; i < list.length; i++) {
int currentNum = list[i];
int findNum = sum - currentNum;
int length = list.length;
int min = i;
int max = length-1;
while(max >= min) {
int guess = (max+min)/2;
if(list[guess] == findNum) {
return new int[] {i,guess};
}
if(list[guess] < findNum) {
min = guess + 1;
}
if(list[guess] > findNum) {
max = guess - 1;
}
}
}
return indices;
}
代码非常简单,对于数组中的每个元素,它都会尝试使用二进制搜索来查找另一个元素,以便它们的总和等于提供的sum
。我已经测试了这段代码,我找不到失败的场景,假设提供的数组已经排序。但是,当我在TestDome上运行此代码时,最后一种情况失败了,它在某种程度上是错误的解决方案。有人能指出这种方法有什么问题吗?
答案 0 :(得分:3)
代码假定列表已排序。问题陈述没有说明元素的顺序,所以你需要自己对数组进行排序。由于您需要索引,因此需要对值对和索引进行排序。
更快的方法是将数据放入带有计数和原始索引的哈希映射中,并检查列表中每个Target - n
是否存在n
。当Target
等于2*n
时,您需要针对特殊情况的计数。
答案 1 :(得分:0)
基于作者关于初始列表的排序顺序的问题和说明,似乎初始列表没有排序。因此需要对列表进行排序,并且原始索引需要单独存储在另一个列表中。
在对数组进行排序并记录原始索引之后,让我们说arr[]
包含排序列表,indices[]
包含arr[]
中相应元素的原始索引。换句话说,indices[i]
给出了元素arr[i]
的原始索引。
现在,您可以按照2-SUM算法查找对:
初始化两个索引变量以查找候选项 排序数组中的元素。
循环,而l&lt;河
NULL
您也可以使用二进制搜索技术代替2-SUM程序。
希望它有所帮助!!
答案 2 :(得分:0)
试试这个解决方案。它对数组进行排序并使用二进制搜索来定位第二个元素,该元素必须是 sum - n 。
如果找到匹配的对,则在原始数组中查找它以确定原始索引:
public static int[] findTwoSum(int[] list, int sum) {
int len = list.length;
int[] sortedList= Arrays.copyOf(list, len);
Arrays.sort(sortedList);
for (int i = 0; i < len; i++) {
int m = list[i];
int j = Arrays.binarySearch(sortedList, sum - m);
if (j >= 0 && i != j)
return new int[] { i, findIndex(list, sortedList[j]) };
}
return null;
}
public static int findIndex(int[] list, int m) {
int len = list.length;
for (int i = 0; i < len; i++) {
if (list[i] == m)
return i;
}
return -1;
}