Find taxicab numbers in $O(n)$ time

This is a final exam question in my algorithms class:

$k$ is a taxicab number if $k = a^3+b^3=c^3+d^3$, and $a,b,c,d$ are distinct positive integers. Find all taxicab numbers $k$ such that $a,b,c,d < n$ in $O(n)$ time.

I don't know if the problem had a typo or not, because $O(n^3)$ seems more reasonable. The best I can come up with is $O(n^2 \log n)$, and that's the best anyone I know can come up with.

The $O(n^2 \log n)$ algorithm:

  1. Try all possible $a^3+b^3=k$ pairs, for each $k$, store $(k,1)$ into a binary tree(indexed by $k$) if $(k,i)$ doesn't exist, if $(k,i)$ exists, replace $(k,i)$ with $(k,i+1)$

  2. Transverse the binary tree, output all $(k,i)$ where $i\geq 2$

Are there any faster methods? This should be the best possible method without using any number theoretical result because the program might output $O(n^2)$ taxicab numbers.

Is $O(n)$ even possible? One have to prove there are only $O(n)$ taxicab numbers lesser than $2n^3$ in order to prove there exist a $O(n)$ algorithm.

Edit: The professor admit it was a typo, it should have been $O(n^3)$. I'm happy he made the typo, since the answer Tomer Vromen suggested is amazing.


Solution 1:

I don't know about $O(n)$, but I can do it in $O(n^2)$. The main idea is to use initialization of an array in $O(1)$ (this is the best reference that I've found, which is weird since this seems like a very important concept). Then you iterate through all the possible $(a,\ b)$ pairs and do the same as step 1 in your proposed algorithm. Since $a^3+b^3 \leq 2n^3$, the array needs to be of size $2n^3$, but it's still initialized in $O(1)$. Accessing an array element is $O(1)$ like in a regular array.

Solution 2:

Apparently this is a solved problem and every rational solution to $x^3 + y^3 = z^3 + w^3$ is proportional to

$x = 1 − (p − 3q)(p^2 + 3q^2)$

$y = −1 + (p + 3q)(p^2 + 3q^2)$

$z = (p + 3q) − (p^2 + 3q^2)^2$

$w = −(p − 3q) + (p^2 + 3q^2)^2$

See: http://129.81.170.14/~erowland/papers/koyama.pdf, Page 2.

Also see: http://sites.google.com/site/tpiezas/010 (search for J. Binet).

So it seems like an O(n^2) algorithm might be possible. Perhaps using this more cleverly can give us an O(n) time algorithm.

Hope that helps. Please do update us with the solution given by your professor.