algorithm – 查找复合数的最小值

如果有一些给定的素数:2,3,5,7

是否有一种有效的方法来找出大于某个给定数字的最小复合数,除了允许的素数之外没有其他素数因子.

例如:
给出素数集:2,3,5,7
如果我们想要找到一个必须大于或等于85的复合数,并且除了2,3,5或7之外没有素因子,答案应该是90.
因为

85 = 5 * 17 (wrong)  
86 = 2 * 43 (wrong)  
87 = 3 * 29 (wrong)  
88 = (2 ^ 3) * 11 (wrong)  
89 = 89 (wrong)  
90 = 2 * (3 ^ 2) * 5 (correct)

最佳答案 您正在找到最小数字2 ^ i 3 ^ j 5 ^ k 7 ^ l,它大于或等于某些N.

我们可以简单地按顺序处理这些数字,直到我们得到一个大于N的数字.

最小的数字是1,对应于(i,j,k,l)=(0,0,0,0).
我们现在将这个元组推到最小堆H并添加到集合S中
(例如,用哈希表实现).

我们现在重复以下内容,直到找到大于N的数字:

>从堆H中弹出最小元素(i,j,k,l)
>将元组(i 1,j,k,l),(i,j 1,k,l),(i,j,k 1,l)和(i,j,k,l 1)添加到H和S,如果他们还没有在S.

这可以确保我们以正确的顺序考虑数字,因为每次删除数字/元组时,我们都会将所有新的候选者添加到堆中.

这是python中的一个实现:

import heapq
N = 85
S = set([(0,0,0,0)])
H = [( 1 , (0,0,0,0) )]
while True:
    val,(i,j,k,l) = heapq.heappop(H)
    if val >= N:
        break
    if (i+1,j,k,l) not in S:
        S.add((i+1,j,k,l))
        heapq.heappush(H,( val*2 , (i+1,j,k,l) ) )
    if (i,j+1,k,l) not in S:
        S.add((i,j+1,k,l))
        heapq.heappush(H,( val*3 , (i,j+1,k,l) ) )
    if (i,j,k+1,l) not in S:
        S.add((i,j,k+1,l))
        heapq.heappush(H,( val*5 , (i,j,k+1,l) ) )
    if (i,j,k,l+1) not in S:
        S.add((i,j,k,l+1))
        heapq.heappush(H,( val*7 , (i,j,k,l+1) ) )

print val # 90

由于序列的大小呈指数级增长,因此迭代次数不会超过O(log N).在每次迭代中,我们最多向H和S添加3个项,因此堆永远不会包含多于O(3 log N)个项.因此,每个堆/集操作的成本不会超过O(log log N),从而确保整个时间复杂度为O(log N * log log N).

点赞