3

I'm now doing exam revision, and from some past year exam papers, I noticed some questions that ask to write a recursive method with signature like

public void run(int n)

that must have a time complexity of like : $O(n^2), O(n^3), O(n^7), O(n^2!), O(2^n), O(9^n)$.

Can anyone give some idea on how to solve this kind of recursion questions.

Kaveh
  • 22,661
  • 4
  • 53
  • 113
Timeless
  • 805
  • 1
  • 9
  • 16

3 Answers3

7

I will assume the person stating the problem actually meant $\Theta$ where you write $O$; otherwise the question is trivial as Juho points out. Realising this may very well have been the point of the problem (or an intended shortcut for the observant), though.

Here is one basic idea to create an algorithm with runtime $\Theta(f(n))$: find a set of objects $S$ with $|S| = \Theta(f(n))$ and recursively enumerate it. If done correctly, this gives you a runtime in $\Omega(f(n))$; if you don't waste time, you get $\Theta(f(n))$.

Some hints for the concrete runtimes you want to achieve:

  • Given a set $T$ of $n$ objects, $|T \times T| \in \Theta(n^2)$.
  • Given a set $T$ of $n$ (distinguishable) objects, the set $\operatorname{Perm}(T)$ of all permutations of these objects has size $n!$.
  • The set $\{0,1\}^n$ contains $2^n$ words.

Note that all these (simple) facts should be known from basic algorithm analysis and formal languages (and maybe combinatorics). The exam question can be solved by generalising and combining them.

Raphael
  • 73,212
  • 30
  • 182
  • 400
2

The idea is quite simple. Write your function run and analyze its time complexity $r(n)$. Is it then so that you can find any nonnegative constant $c$ and input size $n_0$ such that from which $r(n_0) \leq cg(n_0)$, where $g(n)$ is any particular function you desire? This idea comes from the formal definition of Big Oh. It might be helpful to build up intuition by plotting something, see here.

Here's a concrete implementation. It's not very meaningful, but it doesn't have to be.

void run(int n)
{
  if(n == 0) return;
  run(0);
}

The function is recursive and clearly runs in constant time. It is easy to verify by for example plotting, that yes, at some point $n^2$ and $n^3$ start to dominate. Hence, the the time complexity of the implementation is in both $O(n^2)$ and $O(n^3)$. Similar reasoning holds for other functions.

Juho
  • 22,905
  • 7
  • 63
  • 117
-3

When you are given a problem statement there will be an input.The given input has to be countable in some way. In order to get the answer or output you got to manipulate the input in some way are the other in programming. The question is ,how many operation are you going to do on your inputs ... it depends on problem requirement .

For example : In an sorted array of n elements .
      1)searching can be done by checking each and every element . 
      2)And using the mathematical property that array is sorted you apply a very old trick          
       called  binary search .which divedes our search space into half every time we check   
       our trick. This reduces our search space so as reducing the operations.

please read Master theorem to know how to evaluate complexity.

In the case 1 we have complexity in big oh notation as O(n) where n is the input .
In the case 2 we have complexity in big oh notation as O(log(n)) where n is the input .

For basic please refer Big Oh

Coming to the recursion , Suppose our problem be searching, let us consider the binary search .

int binary_search(int A[], int key, int imin, int imax)
{
  // test if array is empty
  if (imax < imin):
    // set is empty, so return value showing not found
    return KEY_NOT_FOUND;
  else
    {
      // calculate midpoint to cut set in half
      int imid = midpoint(imin, imax);

      // three-way comparison
      if (A[imid] > key)
        // key is in lower subset
        return binary_search(A, key, imin, imid-1);
      else if (A[imid] < key)
        // key is in upper subset
        return binary_search(A, key, imid+1, imax);
      else
        // key has been found
        return imid;
    }
}

Firstly for searching an element say X in our input length N then we check middle element in an sorted array to see whether element to be searched(x) is greater or lesser .If it is greater we search the element from middle element(n/2) to last element N recursively .If element to be search(x) is smaller than middle we search from 1 to (n/2) ,as we know that element after middle element is bigger than middle(x

Imposter
  • 167
  • 7