I am practicing algorithm but always confused about time complexity between O(n!) and O(2^n). I know O(2^n) can be understood like select or not select an item from a set, which usually likes recursion (or backtracking?) situation. But backtrack problems sometimes also marked with O(n!)?
Can somebody please explain them in simple language?
The Big O notation does not produce the exact results but rather estimates of growth of functions by specifying some upper bound function. To represent the most relevant families of such functions there are commonly used terms as logarithmic, linear, polymorphic and expotentional. Both O(n!) and O(2^n) fall into the category of expotentional growth. Just O(n!) grows slightly faster.
So as the takeaway conclusion Big O allows some sloppiness and occasionally there are functions that match closer the upper bound but different authors may use either term referring to the same algorithm.
As it comes to backtracking, the choice of the solutions in every step may be limited by the choice done in the previous step so the number of possible choices in every step is reduced by one following the factorial pattern. But not all cases of backtracking fall into this category and some may involve complexity O(2^n) or even O(n^n) if the choice of solutions in every step is independent from previous steps.
EDIT: Corrected growth relations between O(2^n), O(n!) and O(n^n)