我最近被问到这个问题.我轰炸它,我会喜欢它的一些帮助.问题是这样的:
你得到了一个数字列表.数字都是正整数.所以想象他们是这样的:
[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),几乎立即找到一个解.我担心,计算平均案例复杂性并不简单.