查找在排序数组

时间:2017-11-20 18:07:46

标签: python arrays algorithm python-3.x refactoring

我的问题类似于Find all elements that appear more than n/4 times in linear time,你得到一个大小为n的数组,找到所有出现超过n / 4次的元素,区别在于数组是排序的,运行时应该比为O(n)。

我的方法是对位置n / 4,n / 2和3 * n / 4中每个元素的第一次出现进行3次二进制搜索,因为数组已排序,我们可以知道每个元素是否出现多于n / 4次检查下一个n / 4元素是否具有相同的值。

我在python3中编写了以下代码,您认为我的方法是否正确以及是否有任何可以简化的内容?:

import bisect

# return -1 if x doesn't exist in arr
def binary_search(arr, x):
    pos = bisect.bisect_left(arr, x)
    return pos if pos != len(arr) and arr[pos] == x else -1

def majority(arr):
    n = len(arr)
    output = []
    quarters = [arr[n//4],arr[n//2],arr[3*n//4]]

    # avoid repeating answer in output array
    if arr[n//4] == arr[n//2]:
        quarters.remove(arr[n//4])
        quarters.remove(arr[n//2])
        output.append(arr[n//2])
    if arr[n//2] == arr[3*n//4]:
        if arr[n//2] in arr:
            quarters.remove(quarters[n//2])
        if arr[3*n//4] in arr:
            quarters.remove(quarters[3*n//4])
        if arr[n//2] not in output:
            output.append(arr[n//2])

    for quarter in quarters:
        pos = binary_search(arr, quarter)
        if pos != -1 and pos+n//4 < len(arr) and arr[pos] == arr[pos+n//4]:
            output.append(arr[pos])
    return output

print(majority([1,1,1,6,6,6,9,145]))

2 个答案:

答案 0 :(得分:1)

我认为你想要的更像是:

Examine the element at position n/4
Do a binary search to find the first occurrence of that item.
Do a binary search to find the next occurrence of that item.
If last-first > n/4, then output it.

Repeat that process for n/2 and 3(n/4)

如果前一项超出下一个n / 4标记,则有一个早期机会。

答案 1 :(得分:-2)

我会做出以下改进。取位置0,n / 8,n / 4,3n / 8,...,n处的9个值。您只需要考虑重复两次的值。

进行二分查找时,可以同时进行两端搜索。这样,如果最常见的值小得多或大于1/4那么你就不会进行大部分的二元搜索。