找到排序数组的索引,使a [i] + a [j] = x

时间:2014-02-10 20:25:38

标签: arrays algorithm binary-search

这是一个面试问题:给定integer xsorted 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));
    }
}

2 个答案:

答案 0 :(得分:3)

您可以使用以下观察结果将算法修改为线性时间:

  1. 在不失一般性的情况下,您可以说ijarr[i]<arr[j]。证明:如果不是这样,您可以交换ij
  2. 考虑到您在搜索sum-arr[i]时开始搜索,您始终可以搜索索引i的右侧;如果sum-arr[i] < arr[i],您知道没有答案,因为j将位于i的左侧
  3. 如果之前对sum-arr[i]的搜索已在索引k处结束而未产生结果,则您的下一次搜索可以在索引ik之间进行。
  4. 您无需使用二分搜索来搜索sum-arr[i]:您可以从后面进行线性搜索,并将k点作为下一个起点arr[k] < sum-arr[i]
  5. 这使您可以构建一个算法,只检查每个项目一次。

答案 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));
    }
}