5 Methods for Problem Solving
When developing new software algorithms, a systematic approach helps. When confronted with a software problem use the five methods below to come up with an algorithm to solve the problem.
Write out specific examples of the problem and see if you can derive a general rule from there.
Consider what problems the algorithm is similar to and try to modify the solution to the related problem to develop an algorithm for this problem.
Simplify and Generalize
This has a multi-step approach. First, we change a constraint such as the data type or amount of data. Doing this helps simplify the problem. Then we solve this new simplified version.
Base Case and Build
We solve the problem first for the base case: n=1. This usually just means recording the correct result. Then we try to solve the problem for n=2, assuming you have the answer for n=1. Next try for n=3 and then for n=4. Eventually we can build a solution that can solve the result for N if we know the correct result for N-1. This often leads to a naturally recursive algorithm.
Data Structure and Brainstorm
This is a hacky approach but often works. We can simply run through a list of data structures and try to apply each one. This approach is useful because solving a problem may be trivial once it occurs to us to use, say, a binary search tree. 2
Algorithm Implementation Notes
Implement primitive data structures first such as Node or Record, then the data structures that use them, such as List or HashTable. Implement the insert function first, then search, remove, size, print, etc. For recursive functions, implement a shell insert function that then calls a private recursive helper function: “def insert” (public) then “def __insert” (private). The basic template for recursive functions is to do a basic “null” check on input data and then call a recursive helper function. When implementing if/elif/else statements, handle the simplest case first: node is None, then edge cases. Be consistent in how you develop a solution. Write unit tests as you implement each function, that way you catch bugs as you are developing and not all at the end.