How to approach a DSA problem?

Understanding the problem

  • The first step in approaching a DSA problem is to understand the essence of the problem itself. We must try to figure out what the problem demands.
  • Not understanding the basic needs of the problem asked is a big mistake. If the wording of the question is unclear, look at the test cases given for the particular problem and try to reverse-engineer the demands of the question.

Clearing out a logical path

  • The second step involves building a clear picture of the answer's logic in our head. If the logic of your answer statement is fairly complicated, consider writing down comments while implementing the logic in your code.
  • Once the logic is thought of, try to think of alternate ways to approach the problem if it doesn't meet the complexity constraints. Repeat this step until you're happy with your desired logic for the answer. Using pseudocode or diagrammatic representations to refine the algorithm before coding can help to understand the logic and essence of the program well.

Effective Implementation

  • Implement the logic in your code. As said before, consider adding comments to your code to make the logic "flow" better while solving it. Eventually, with enough problem-solving, you won't require the comments to implement logic(s) anymore, though it is a good habit to do so.
  • Another "cosmetic" tip is to name your variables well. Try to use as few variables as possible to minimize the storage space required for your code. Try to include various problem-solving paradigms such as greedy, dynamic programming, divide and conquer paradigms to guide the design of your algorithms.

Testing and submission

  • Once implemented, test your code. Your code should be tested on an exhaustive set of inputs and outputs. This exhaustive testing will allow you to find and fix any edge cases that slipped under the radar the first time.
  • Try to think about why your code breaks at that edge case and see if it's a basic logical fallacy in your code or simply a case that could have slipped between the cracks during the implementation.
  • Try using systematic debugging techniques such as print statements, debugging tools, or test case generators to identify and resolve errors more efficiently. This would allow you to pinpoint the source of all the errors and allow you to fix them surgically.

Dealing with fallacies

  • If all else has failed, try a brute force method to meet all the constraints of the problem and work your way from there. Try to look at your logic and think about ways it can be optimized, even at the cost of storage space. Try to think of any way to make your code run faster.
  • Try to think of more "elegant" ways that would not require recursion in any form. Thinking about creative ways to solve problems will allow you to level up your skills as well as make you think about the logic of your program more deeply.

Effective debugging

  • Breaking your code down into smaller parts would allow you to approach the problem in a more appealing way, allowing you to debug and test it easily. Identify patterns between logic(s) of various problems and think about why they resemble each other.
  • Try thinking about possible trade-offs between speed and memory usage. Balancing both is key in real-world situations.

Patience is key

  • Most importantly, you must be patient throughout the whole process. Getting stuck is a part of the journey. Apart from that, solving more DSA problems will make you better at it. That is pretty much true for every replicable activity. Solving more problems, especially harder questions, would allow you to step out of your comfort zone by a lot.
  • Learning new algorithms, mathematical formulas, etc. are all things that would make you a better programmer in the long run.

Attribution

This wiki was maintained/written by Triach Rold.