【问题标题】:Find element in a sorted array在有序数组中查找元素
【发布时间】:2017-04-10 03:44:27
【问题描述】:

给定一个排序数组A 和一个元素x,我需要找到一个算法,如果x 不在A 中,则返回xA-1 中的索引。 算法的时间复杂度应该是Θ(logd),当d是A中出现在x之前的元素数,或者如果x不在A中,d是之前的元素数x 如果他在A

二分查找还不够好,因为它的最佳情况是 O(1)。 我想从数组的开头开始,然后开始检查 2 的幂的索引。但我迷路了。

【问题讨论】:

  • 二分查找最坏情况 O(log n)…
  • 如果是你想要的log(size(A)),二分查找就可以了。如果您尝试根据x 的位置进行优化,我的直觉是检查2 的幂,直到找到大于x 的值,然后在上半部分进行二分搜索,但我不是完全清楚你在问什么。
  • @taylorswift 我知道,但我需要Θ(logd),这意味着最好的情况也是 logd,它在二进制搜索中不正确。
  • @Genadi ,我不确定你是否理解最佳情况和最坏情况复杂性的含义,最坏情况意味着算法可以永远无论输入如何,都需要比 O(log n) 更长的时间来执行此搜索。如果你需要一个 O(log n) 算法,那么每个 O(1) 算法都满足,因为 O(1)
  • 根据你的符号,你的意思是说平均时间复杂度应该是logd。任何算法的最佳情况都可能是O(1) 纯属偶然/巧合

标签: arrays algorithm search time-complexity


【解决方案1】:

您可以这样做:它使用 Θ(log d) 步骤来查找大小为 Θ(d) 的范围,然后在另一个 Θ(log d) 步骤中在该范围内进行二分搜索。

int search(int[] array, int length, int valueToFind)
{
    int pos=0;
    int limit=min(length,1);
    while(limit < length && array[limit] < valueToFind)
    {
        pos=limit+1;
        limit = min(length, limit*2+1);
    }
    while(pos<limit)
    {
        int testpos = pos+((limit-pos)>>1);

        if (array[testpos]<valueToFind)
            pos=testpos+1;
        else
            limit=testpos;
    }
    return (pos < length && array[pos]==valueToFind ? pos : -1);
}

请注意,我使用的二进制搜索不会提前退出,并且总是需要 Θ(log (limit-pos)) 时间。即便如此,它也比其他提前退出的搜索要快,因为它每次迭代只进行一次比较。我在这里描述其他优点:

How can I simplify this working Binary Search code in C?

【讨论】:

  • 太好了!运算符&gt;&gt; 是什么意思?
  • @Genadi >>1 表示右移 1 位。它与 /2 相同,但除法总是向下舍入而不是向 0 舍入,即 5>>1 == 2 和 -5 >>1 == -3。在这个应用程序中,差异并不重要——我可以写 /2,但我老了,我记得有一次性能差异。
【解决方案2】:

我有一个简单的python 实现,它基于 cmets 部分中讨论的2's 方法的强大功能。请看:

def binary_search(nums,low,high,x):
  while low<=high:
    mid = (low+high)/2
    if nums[mid]==x:
      return mid+1
    elif nums[mid]>x:
      high = mid-1
    else:
      low = mid+1
  return -1

def find_index(nums,x):
  i = 1
  l = len(nums)
  while i<l:
    if nums[i-1]==x:
      return i
    elif 2*i<l and nums[2*i-1]>x:
      return binary_search(nums,i-1,2*i-1,x)
    i = 2*i
  return binary_search(nums,i/2,l-1,x)

def main():
  line = raw_input("Enter numbers: ").split()
  nums = []
  for ele in line:
    nums.append(int(ele))

  nums = sorted(nums)
  print "Sorted array: ",nums
  x = int(raw_input("Enter the element to find in sorted array: "))
  print find_index(nums, x)

main()

首先,它尝试通过移动 2 的幂 的索引来找到目标元素。

如果当前元素超过目标元素,那么我们在当前索引(当前2的幂)上一个索引(之前的幂)之间做一个binary search 2).

搜索过程的时间复杂度平均为logd。最好的情况时间复杂度也是logd,正如预期的那样!!

希望通俗易懂!!!!

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多