我的问题类似于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]))
答案 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那么你就不会进行大部分的二元搜索。