算法 – 给定一个包含43亿个32位整数的文件,我们怎样才能找到一个至少出现过两次的数字?

我已经为此提出了分而治之的算法.只是想知道这是否有效?

第一个mid从整数范围计算,即(0(1 <32-1))> 1然后应用这个想法:从开始到中间或从中到中的数字范围总是小于我们将考虑的数字,因为我们正在考虑十亿数字,肯定会有一些数字会重复,因为32位整数的范围比十亿数字要小得多.

def get_duplicate(input, start, end):  
  while True:
    mid = (start >> 1) + end - (end >> 1)
    less_to_mid = 0
    more_to_mid = 0
    equal_to_mid = 0
    for data in input:
        data = int(data, 16)
        if data < mid:
            less_to_mid += 1
        elif data == mid:
            equal_to_mid += 1
        else:
            more_to_mid += 1
    if equal_to_mid > 1:
        return mid
    elif mid-start < less_to_mid:
        end = mid-1
    elif end-mid < more_to_mid:
        start = mid+1

with open("codes\output.txt", 'r+') as f:
  content = f.read().split()
  print(get_duplicate(content, 0, 1<<32-1))

我知道我们可以使用位数组,但我只想获得您对此解决方案的看法,以及实现是否有问题.

最佳答案 你的方法没问题.但您可能需要多次读取输入才能找到答案.

这是一个变体,它允许您找到内存很少的副本,但您只需要读取输入两次.

>将整数的数组A [65536]初始化为零.
>逐一阅读数字.每次读取数字x时,将1加到A [x mod 65536].
>当读数结束时,将存在至少一个i,使得A [i]严格大于65536.这是因为65536 * 63356< 43亿.我们说A [i0]大于65536.
>将阵列A清零.
>再次读取数字,但这一次,只看那些数字x,使得x mod 65536 = i0.对于每个这样的x,将1加到A [x / 65536].
>当读数结束时,将至少有一个j使得A [j]严格大于1.然后数字65536 * j i0是最终答案.

点赞