给定一个具有正整数和负整数的无限长度排序数组。在其中找到一个元素。
修改
数组中的所有元素都是唯一的,并且数组在正确的方向上是无限的。
有两种方法:
将索引设置在位置100,如果要找到的元素较少,则在前100个项目中进行二进制搜索,否则将下一个索引设置在位置200.这样,继续将索引增加100直到该项目更大。
将索引设置为2.首先将索引设置为位置2,然后设置为4,然后设置为8,然后设置为16,依此类推。再次进行二元搜索,从位置2 ^ K到2 ^(K + 1),其中项目介于两者之间。
在最佳情况和最差情况下,这两种方法中的哪一种会更好?
答案 0 :(得分:18)
第一种方法在元素的索引中是线性的(O(k)
,其中k
是元素的索引)。实际上,您需要k/100
次迭代才能找到大于搜索元素的元素,即O(k)
。
第二种方法将在同一索引中进行对数。 O(logk)
。 (其中k
是元素的索引)。在这里,您将需要log(k)
次迭代,直到找到更高的元素。然后,2^(i-1)
,2^i
(其中i
是迭代次数)之间的二进制搜索也将是对数的,总计为O(logk)
因此,第二个效率更高。
答案 1 :(得分:3)
如果数组是有根据的,即具有最小元素(即你有元素 x 0 , x 1 ,...),并且所有元素都是唯一的,那么这是一个简单的方法:如果你正在寻找数字 n ,你可以对索引0进行二元搜索, ..., n - x 0 。请注意,我们总是有基本的不等式 x i ≥ i + x <所有 i ≥0的sub> 0 。
因此,您可以在log 2 中找到值 n ( n - x 0 < / sub>)步骤。
答案 2 :(得分:1)
您可以通过一些小修改直接或多或少地应用二进制搜索。这大致对应于您的方法2。
基本上,选择一些数字B并将A设置为0,然后检查您要查找的元素是否在A和B之间。如果是,则在这些边界中执行通常的二分搜索,否则设置B = A和A = 2 * A并重复。这将采用O(log(M)),其中M是您在数组中寻找的元素的位置。
答案 3 :(得分:1)
由于数组是无限的,索引必须是可变长度的。这意味着对它们进行数学运算不是O(1)
,这反过来意味着“首先搜索端点的二进制搜索”与O(log(k))
的时间复杂度略有不同。
在搜索端点时完成的索引数学只是左移一,取O(log(k))
,因为最多k
的索引需要最多log(k)
位并向左移位一个是位数的线性。
二进制搜索中完成的索引数学也是O(log(k))
。
因此两种算法的实际复杂度为O(log(k)^2)
。线性搜索的复杂性为O(k log k)
,因此它仍然会丢失。
答案 4 :(得分:0)
只需2美分。我们有一个无限阵列因此可以想象我们正在寻找非常大的数字。你有没想过?嗯,它会变得更大。请注意,二进制搜索的间隔长度为2^i = 2^(i+1)-2^i
,因此查找数字需要log(2^i)=i
时间。另一方面,达到目标间隔需要i
时间。因此,总时间复杂度再次为O(n)
。我缺少什么?
答案 5 :(得分:0)
Here是另一个实现,它使用2 ^ n来搜索元素本身的出现,然后将该子数组赋予二进制搜索
e.g.
arr = 1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1...........
num = 8;
efficiency = 2logn
答案 6 :(得分:0)
-完整的解决方案-占用O(logn)时间复杂度
公共B类{
public static void main(String[] args) {
// Assuming sorted array of infinite length
int a[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
int elementToFind = 12;
int finalIndex = getFinalIndex(a, elementToFind);
if (finalIndex == -1) {
System.out.println("Element not found");
}
System.out.println("Found element:" + a[finalIndex]);
}
private static int getFinalIndex(int[] a, int elementToFind) {
int power = 2;
int finalIndex = (int) Math.pow(2, power);
for (int i = 0; i < finalIndex;) {
if (elementToFind == a[finalIndex]) {
return finalIndex;
}
else if (elementToFind < a[finalIndex]) {
System.out.println("search through binary search algo");
// taking i as starting index in binary search call
int searchedIndex = callToBinarySearch(a, i, finalIndex);
return searchedIndex;
}
else {
i = finalIndex + 1;
power = power * 2;
finalIndex = (int) Math.pow(2, power);
}
}
return -1;
}
}