这是一个面试问题:给定integer x
和sorted array a[] of N distinct integers
,设计linear-time algorithm
以确定是否存在两个不同的索引i和j,使a[i] + a[j] == x
。不允许辅助存储。
我在Java
中实现了这一点。但我当前的运行时间为O(nlogn)
,因为我在binarySearch
上执行each iteration
。所以它不是严格linear
。我想知道这个问题是否存在linear time solution
。如果是这样,有关它的一些指示可能会有所帮助。
感谢。
public class SumArrayIndex {
public static void main(String[] args){
int[] arr={1,2,3,4,5,6,7,8,9,10};
sumSortedArray(arr, 4);
System.out.println();
sumSortedArray(arr, 19);
System.out.println();
sumSortedArray(arr, 100);
}
public static void sumSortedArray(int[] arr, int sum){
for (int i=0;i<arr.length;i++){
int temp=Arrays.binarySearch(arr, sum-arr[i]);
if (temp>0 && temp!=i){
System.out.printf("The two indices are %s and %s%n ",i,temp);
return;
}
}
System.out.printf("The sum:%s cannot be formed with given array:%s",sum,Arrays.toString(arr));
}
}
答案 0 :(得分:3)
您可以使用以下观察结果将算法修改为线性时间:
i
和j
是arr[i]<arr[j]
。证明:如果不是这样,您可以交换i
和j
。sum-arr[i]
时开始搜索,您始终可以搜索索引i
的右侧;如果sum-arr[i] < arr[i]
,您知道没有答案,因为j
将位于i
的左侧sum-arr[i]
的搜索已在索引k
处结束而未产生结果,则您的下一次搜索可以在索引i
和k
之间进行。sum-arr[i]
:您可以从后面进行线性搜索,并将k
点作为下一个起点arr[k] < sum-arr[i]
这使您可以构建一个算法,只检查每个项目一次。
答案 1 :(得分:1)
正如@leif在评论中所建议的那样,从array
的开头和结尾开始,如果总和大于或小,则移动开始索引或结束索引。你应该找到一个开始和结束index
,使它们的值等于sum
。如果没有,你就没有这样的指数。下面这一行的东西。我没有测试过这段代码并假设为正整数
以下代码不言自明:
public static void sumSortedArray2(int[] arr, int sum){
boolean found=false;
int max=arr.length-1;
int min=0;
while (min<max){
if(arr[min]+arr[max]<sum)
min++;
else if (arr[min]+arr[max]>sum)
max--;
else {
found =true;
break;
}
}
if (found){
System.out.printf("The two indices are %s and %s%n ",min,max);
}
else {
System.out.printf("The sum:%s cannot be formed with given array:%s",sum,Arrays.toString(arr));
}
}