所以我遇到了一个巨大的障碍......也许只是因为我的逻辑不存在,但我似乎无法自己解决这个问题。
我尝试修改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);
}
答案 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的想法远比代码简单得多,因为您不必使用更改的逻辑重新制作二进制搜索。