I'm trying to prove that the following recurrence relation has a runtime of O(n):

 fac(0)   = 1
 fac(n+1) = (n + 1) * fac(n)

I think that I can use induction in the following manner:

Base case

If n=0 then fac(n) = fac(0) = 1

Inductive case

Assume that fac(n) has a runtime of O(n)

fac(n+1) = (n + 1) * fac(n)

Therefore fac(n+1) has a runtime of O(n+1)

However, I have a suspicion that my inductive case doesn't really prove much. Maybe this is because the my assumption for the inductive case is wrong?

Can you point me in the right direction to prove this runtime?

  • $\begingroup$ I hope this doesn't appear too pedantic and, will help to address some underlying misunderstandings. You don't "prove a notation" as notation is just a way of writing stuff down: you're trying to prove an upper bound. Recurrences don't have runtimes: they just define maps from integers to integers. Now the big question: are you treating the recurrence as a function definition in a prog. lang. such as ML or Haskell, in which case it makes sense to ask about the running time of that function (and it is $O(n)$) or are you asking for an upper bound on the value of fac(n) (which is $n!$)? $\endgroup$ – David Richerby May 25 '14 at 15:12

In essence, your proof is correct. A more general solution that you can use for recursive algorithms is this.

The way to solve this is to create a function T(n) that measures the runtime of the function and figure out the big O notation for it.

To solve a problem of size n, I must solve a problem of size n - 1. Then I must perform constant time arithmetic to get the answer. Thus :

T(n) = T(n - 1) + O(1)

Prove T(n) is O(n) ie by definition

T(n) <= cn for all n >= n0


T(n - 1) <= c(n - 1)


T(n) = T(n - 1) + O(1)
T(n) <= c(n - 1) + d
T(n) <= cn + d - c
T(n) <= cn for c >= d

use T(1) as a base case to complete the proof, giving you n0 = 1

| cite | improve this answer | |
  • 1
    $\begingroup$ Welcome to Computer Science! Note that you can use LaTeX here to typeset mathematics in a more readable way. See here for a short introduction. $\endgroup$ – FrankW May 25 '14 at 20:54

Here is a similar example. Consider the recurrence $$F_n = \begin{cases} n & n \leq 1, \\ F_{n-1} + F_{n-2} & n > 1. \end{cases}$$ Let's prove by induction that the runtime to calculate $F_n$ using the recurrence is $O(n)$. When $n \leq 1$, this is clear. Assume that $F_{n-1},F_n$ are calculated in $O(n)$. Then $F_{n+1}$ is calculated in runtime $O(n) + O(n) + O(1) = O(n+1)$.

There is something wrong about this proof — to start with, the result is wrong: calculating the Fibonacci sequence recursively takes exponential time. The problem is that every big O carries with it a hidden constant, and this constant grows in our example.

In order to do things properly, we fall back to the definition of $O(n)$: a function $f(n)$ is $O(n)$ if for some $K,N$ and all $n \geq N$, $f(n) \leq Kn$. In your case you can take $N = 1$. Find an appropriate $K$ and prove by induction that the runtime of your recurrence is at most $Kn$ for $n \geq 1$.

| cite | improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.