Top Down is when you take the whole problem and break it down into smaller and smaller problems until you get to the bottom where you have lots of actual implementation details.
Bottom Up is when you create lots of small, detailed building blocks that are generally useful and that can be assembled together to solve larger and larger problems.
Top down is useful for analyzing and understanding how a large problem can be broken down into areas of responsibility and produces the overall structure of a piece of software. One drawback is that it tends to produce task specific code at the bottom that is generally hard to reuse in other applications.
Bottom Up, on the other hand, is often the approach that library builders take. It is entirely focused on producing small components that are as generic and reusable as possible within their specific areas of utility.
When (re)designing a whole system both approaches are important. Initially the Top Down approach will give you a logical structure specific to the application. Once that has been achieved the Bottom Up approach can be applied where the low-level specifics are addressed. This could mean locating relevant libraries that are well matched for solving lower tier problems or embarking on an in-house library based solution.
The point being that the actual implementation code should be as reusable as possible. That way creating successive applications should get progressively cheaper. To that end the Top Down approach can only take you so far and at that point the Bottom Up approach fills in the gaps with something less specific to the current task but more useful to tasks in general.