算法 – 给定一个候选列表,我们可以在线性时间内达到目标值吗?

我最近被问到这个问题.我轰炸它,我会喜欢它的一些帮助.问题是这样的:

你得到了一个数字列表.数字都是正整数.所以想象他们是这样的:

[x_0, x_1, ..., x_{n-2}, x_{n-1}]

所以我们有n个数字.无法保证数字不同.我们也有目标价值.我们称之为X.X也是一个正整数.

如果我们可以用以下形式的候选者表达目标数X,那么目标是输出布尔值只有True / False:

a * x_0 + b * x_1 + ... 

系数的唯一约束是它们也必须是大于或等于0的正整数.

您可以通过对候选人数字进行一些数学计算来获得线性时间的答案.但是,如果我能看到算法更加充实,我很好奇.它不需要编码 – 我可以这样做 – 但我仍然没有完全算法.我想的可能与Sieve of Eratosthenes或者甚至是Diophantine Equation的方法类似.无论如何,我无法在网上任何地方找到解决方案的清晰写法,并且好奇这个问题是如何被探索的更多.

有人有想法吗?再次感谢!真的很感谢你的帮助!

最佳答案 使用筛子的解决方案可能如下所示:

创建一个大小为X 1的布尔数组,其中零设置为true,所有其他值设置为false.然后,为每个值xi

>如果xi已设置为true,则跳至下一个值(之前的数字组合可用于形成xi及其所有倍数).
>否则,迭代数组(从0到X-xi)并且对于每个值xk都为真,将xk xi设置为true.
>只要值X设置为true,返回true.

首先将值从小到大排序可能会增加跳过某些值的可能性.

例:

X = 21, x = {4, 6, 8, 10, 11, 13, 15}  

 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21  
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

x = 4:  
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21  
{1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0}

x = 6:  
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21  
{1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}

x = 8: skip

x = 10: skip

x = 11:
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21  
{1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}
10 + 11 = 21  ->  return true

最坏的情况(没有跳过值,结果是假的)复杂性是N×X,而在最好的情况下(x的第一个值除以X),几乎立即找到一个解.我担心,计算平均案例复杂性并不简单.

点赞