我在准备考试时遇到了考试问题而且我坚持了下来。 问题是:
设计一种算法,给定一组正整数X,确定方程x 5 + xy - y 2 = y 3 有一个x和y都属于X的解决方案。
不涉及编程,只是算法设计。有人可以分享他们的想法吗?
蛮力是不可接受的
答案 0 :(得分:2)
伪代码:
result = false
foreach (x in X) {
foreach (y in X) {
if (x^5 + x*y - y^2 == y^3) result = true
}
}
是否比预期更复杂?如果是这样,可以利用这样的高阶项x^5
:
Sort X as a list from least to greatest.
result = false
foreach (y in X) {
v = y*y*(y+1)
foreach (x in X) {
x2 = x*x
u = x2*x2 + x*y - v
if (u == 0) {
result = true
goto [DONE]
}
if (u > 0) goto [NEXT]
}
[NEXT]
}
[DONE]
答案 1 :(得分:2)
对于(真的!)大输入,你可以:
x
,因此等式成为y
的立方数,则该公式适用。但是这个公式可能需要很长时间,为了避免可能的精度问题,你可以插入答案来检查它。然后在排序列表(O(logn))上进行二进制搜索。这将渐近地采用O(nlogn),但是常数因素很可怕并被大哦隐藏(好吧,如果你回答问题,不编码程序)。当然,如果允许散列(通常是面试的情况,但不一定是考试),这可能是O(n)。
答案 2 :(得分:2)
作为x的函数求解y:http://www.wolframalpha.com/input/?i=x%5E5%2B+xy+-+y%5E2+-+y%5E3
y(x) := INSERT_EQUATION_HERE
any((y in setX) for y in y(x) for x in setX)
这需要O(| X |),即线性时间。
或者,如果您没有使用具有any
功能或列表操作的语言,那么您的解决方案必须更加冗长:
for x in setX:
possibleYs = solveForY(x)
for y in possibleYs:
if y in setX:
return SOLUTION:(x,y)
return NO_SOLUTION
你实际上不必像我上面所示那样解决二维多项式。相反,您可以考虑集合中的每个x;这修复了x并给出了y中的多项式。然后在恒定的时间内求解该多项式。例如,如果x = 0,我们找到y ^ 2 = = y ^ 3的3个解;如果x = 1,我们会发现2-y ^ 2 = = y ^ 3的3个解,如果x = -0.52,我们等等。解是http://en.wikipedia.org/wiki/Cubic_function#General_formula_of_roots
问题的更一般版本:
如果考虑任意多项式,请注意此方法在以下情况下只能提供O(1)效率:min(max_x_degree,max_y_degree)< 5。这是因为,正如在Galois theory中所证明的那样,具有某些闭合形式解的唯一多项式是4阶或更小的那些。在这个问题中,我们可以将具有最高度数的变量转换为常数。
这并不是说在min(max_x_degree,max_y_degree)<5的情况下,其他方法无法获得O(1)效率。
如果增加变量数量,事情也会变得更有趣。
答案 3 :(得分:0)
如果集合X不是很大,则可以通过构造2D矩阵来实现简单的强力算法。