In computer science, a problem is said to have overlapping subproblems if the problem can be broken down into subproblems which are reused several times or a recursive algorithm for the problem solves the same subproblem over and over rather than always generating new subproblems.[1][2][3]
For example, the problem of computing the Fibonacci sequence exhibits overlapping subproblems. The problem of computing the nth Fibonacci numberF(n), can be broken down into the subproblems of computing F(n − 1) and F(n − 2), and then adding the two. The subproblem of computing F(n − 1) can itself be broken down into a subproblem that involves computing F(n − 2). Therefore, the computation of F(n − 2) is reused, and the Fibonacci sequence thus exhibits overlapping subproblems.
In the following two implementations for calculating fibonacci sequence, fibonacci uses regular recursion and fibonacci_mem uses memoization. fibonacci_mem is much more efficient as the value for any particular n is computed only once.
When executed, the fibonacci function computes the value of some of the numbers in the sequence many times over, whereas fibonacci_mem reuses the value of n which was computed previously:
The difference in performance may appear minimal with an n value of 5; however, as n increases, the computational complexity of the original fibonacci function grows exponentially. In contrast, the fibonacci_mem version exhibits a more linear increase in complexity.