修改二进制搜索java

时间:2013-04-08 01:31:27

标签: java algorithm binary-search

所以我遇到了一个巨大的障碍......也许只是因为我的逻辑不存在,但我似乎无法自己解决这个问题。

我尝试修改BinarySearch以便获取两个索引。

第一个索引是给定数字x和最右边的最左边索引。如果该数字不存在则产生[-1,-1]。

反正。我一直在尝试修改BinarySearch,但似乎无法使其正常工作。任何指针都将非常感激。

public static Pair BinarySearchDup(int[] A, int x, int low, int high){
    int mid = (low + high) / 2;
    int left = -1, right = -1;
    while(low <= high){
        mid = (low + high) / 2;
        if(A[mid] == x){
            int newMid = mid;
            //check left
            if(left == -1){
                left = mid;
                return BinarySearchDup(A, x, low, mid - 1);
            }
            else if(right == -1){
                right = mid;
                return BinarySearchDup(A, x, newMid + 1, high);
            }       
            return new Pair(left, right);
        }
        else if(A[mid] < x)
            return BinarySearchDup(A, x, mid + 1, high);
        else// (A[mid] > x)
            return BinarySearchDup(A, x, low, mid - 1);
    }
    //if there are no matches of the number then it returns -1
    return new Pair(-1, -1);
}

2 个答案:

答案 0 :(得分:0)

我不确定我理解你的想法,但这就是为什么它不起作用的原因:

您的代码相当于:

public static Pair BinarySearchDup(int[] A, int x, int low, int high){
    int mid = (low + high) / 2;
    if(low <= high){        
        if(A[mid] == x)
            return BinarySearchDup(A, x, low, mid - 1);
        else if(A[mid] < x)
            return BinarySearchDup(A, x, mid + 1, high);
        else// (A[mid] > x)
            return BinarySearchDup(A, x, low, mid - 1);
    }

    return new Pair(-1, -1);        
}

实际上,如果你进入while循环,你总是返回,所以永远不会有多次迭代。此外,如果mid的值是x,那么因为left是-1,所以你总是输入这个if子句。或者,如果您不输入while循环,则只返回(-1,-1)。 希望这会有所帮助。

编辑: 难道你不能只使用普通的二进制搜索,然后只是从找到的索引中来回走,直到得到整个范围?

答案 1 :(得分:0)

解决这个问题:

我正在尝试修改BinarySearch,以便获取两个索引。 第一个索引是给定数字x和最右边的最左边索引。如果该数字不存在则产生[-1,-1]。

我会这样做:

1)进行二分搜索,除了不考虑目标匹配并立即结束,认为它比目标大(例如你在其左边搜索)。当此搜索结束时,它将位于目标的最左侧实例,一个左侧(取决于它的编码方式 - 在这种情况下只检查一个)或者将确认不存在。

2)执行二分类搜索,如1))除了考虑小于目标的目标。这将以类似的方式找到目标的最右侧实例。

这为您提供了O(logN)的复杂性。 Petar Ivanov的想法是“你不能只使用正常的二进制搜索,然后只是从找到的索引中来回走,直到得到整个范围?”如果数组中有大量重复项,则可能与O(N)一样糟糕。但是,如果预期的重复计数(或预期的数组大小)很小,那么Petar Ivanov的想法远比代码简单得多,因为您不必使用更改的逻辑重新制作二进制搜索。

相关问题