为了记录,我在某个Web编码站点上遇到了这个问题,但是我对我错过的内容而不是分数很感兴趣。在这里:
实现函数countNumbers,该函数接受排序的唯一整数数组,并计算小于参数lessThan的数组元素的数量。
例如,SortedSearch.countNumbers(new int[] { 1, 3, 5, 7 }, 4)
应该返回2
,因为有两个数组元素少于4
。
我提供以下解决方案,但是,我无法确定在哪种情况下它将失败? (该网站表示未通过4个测试中的1个)。而且我也不确定我可以对值lessThan
做出什么样的假设。
public class SortedSearch {
public static int countNumbers(int[] sortedArray, int lessThan) {
if (sortedArray == null || sortedArray.length == 0)
return 0;
if (sortedArray.length == 1) {
return sortedArray[0] < lessThan? 1:0;
}
int left = 0;
int right = sortedArray.length-1;
int middle = 0;
while(left<right) {
middle = left + (right-left)/2;
if (sortedArray[middle]<lessThan) {
left = middle+1;
} else if (sortedArray[middle]>lessThan) {
right = middle-1;
} else {
return middle;
}
}
return left;
}
public static void main(String[] args) {
System.out.println(SortedSearch.countNumbers(new int[] { 1, 3, 5 }, 4));
}
}
答案 0 :(得分:2)
您的代码当前正在执行经典二进制搜索。您需要修改以包括您的案件。
例如。 尝试使用以下测试用例编写代码:
{ 1, 3, 5 }, 4) -> should output 2
{ 1, 3, 5 }, 2) -> should output 1
{ 1, 3, 5 }, 3) -> should output 1
{ 1, 3, 5 }, 6) -> should output 3
{ 1, 3, 5 }, 0) -> should output 0
其中大多数都无法使用现有代码。
我们的目标是找出给定数字middle
小于和middle + 1
大于的点。当然,我们可以使用二进制搜索(已修改)来做到这一点。
我修改了您的经典二进制搜索代码,以包括以下情况(以及代码中添加的注释):
while (left <= right) {
middle = left + (right - left) / 2;
if (sortedArray[middle] < lessThan && (middle + 1) < sortedArray.length
&& sortedArray[middle + 1] > lessThan) {
// we have the point where middle is less and middle+1 is greater than given num
return middle + 1;
} else if (sortedArray[middle] == lessThan) {
// we have found the number itself
return middle;
} else if (sortedArray[middle] < lessThan) {
// recur in right part
left = middle + 1;
} else if (sortedArray[middle] > lessThan) {
// recur in left part
right = middle - 1;
}
}
// given number is either lesser/bigger than all elements in the array
return lessThan < sortedArray[0] ? 0 : sortedArray.length;
答案 1 :(得分:1)
仅更改1
。
while(左<右)
到
while(左<=右)
答案 2 :(得分:1)
像您一样的二进制搜索功能是我的宠儿之一。我写了一些我认为通常是在此处写的最好方法:How can I simplify this working Binary Search code in C?
这特别适合您的情况。由于您尝试查找位置而不是元素,因此可以通过每次迭代仅进行一次比较来简化代码并使之更快:
public static int countNumbers(int[] sortedArray, int lessThan) {
int start = 0, limit = sortedArray.length;
while(start < limit) {
int test = start + ((limit-start)>>1);
if (sortedArray[test] < lessThan) {
start = test+1;
} else {
limit = test;
}
}
return start;
}
请注意,没有特殊情况需要处理,如果数组包含重复的元素,这也将起作用。