Sharpen your Problem Solving Skills as a Programmer

If you have been following this blog, you probably know by now that I love playing around with algorithms and data structures.

Recently, I was sick, so I took a break from blogging. 

While I was resting, maybe because I don't have much to do, I began to think a lot.

One of the things that popped into my mind was the following question

How does a programmer effectively improve their problem solving skills?

Click to Tweet

The most immediate answers that popped into mind head are the following actionable items.

  • Solve as many problems as possible.
  • Work on a side-project.
  • Solve problems with somebody else and bounce your thoughts off them.
  • Take a class.
  • Watch a video on problem solving.

Don't get me wrong. These answers are not wrong.

However, I felt that the root cause of a majority of the pain points in problem solving remains largely unanswered, leaving much to be desired.

Below, is what I think is the root cause.

More...

Jay LeeSome Random Guy on the Internet

As programmers, sometimes, the reason why we remain stagnant in our journey to become better problem solvers is because we don't take time to

study the process of understanding the problem.

If the explanation above seems generic or somewhat vague, don't worry about it for now.

By the end of this tutorial, this quote will make sense and stick to you like glue. 

Prepare to sharpen your skills as a problem solver! Or at least, gain a fresh perspective when approaching problems.

1. Problem Solving in the Context of Programming

This might sound redundant, but believe me when I say that we are going somewhere with this.

To developers, problem solving skills is equivalent to the skills of wielding a sword and a shield to a medieval soldier.

Without a doubt, warriors who forget to bring their weapons to the battlefield​ will be slaughtered or effectively rendered useless.

In the same way, problem solving skills are our lifeline. We live and die by our ability to, analyze, break down and solve problems.​

Just as warriors fight against the soldiers in an opposing army, as programmers, we wage war against problems that come to us on a daily basis.

Every function that we write is/should be an answer to a specific problem.

Instead of fighting with swords and shields, as nerdy as this may sound, we fight with code. 

For example, creating a function that logs data to the console addresses our need to see the actual data and its value at a certain time of the program's execution.

1.1 Why are some problems so challenging? 

While some problems that we face are relatively simple, others often come off as very challenging. Let me propose to you a list of possible reasons why certain problems seem so difficult to us.

  • Maybe its your first time facing a particular problem
  • The sheer complexity of the problem itself overwhelmed you and shut your brain down
  • The problem was presented ambiguously.
  • While the activities don't see complex, the scale of the project is extremely large, which you feel, will result in unforeseen cases.

Try and think of any other possible reasons why problems appear to be challenging. If you do, please drop a comment and let me know. I will most likely update this post and add more content. 

1.2 Important Skills for Solving Problems

On of the most important soft skill that programmers need, when solving problems is the ability to gather information.

The more important information we have, the easier it becomes to understand the problem that we have.

The second most important skill is analyzing and extracting concrete information and facts from these sources.

We extract information by analyzing the problem that we have and asking questions. 

The questions we ask will depend on the problem.​

Some general questions we can ask are

  • What are the key variables that we need to be mindful of?
  • What are some underlying assumptions?

2. Worst Ways of Solving Problems

I am guilty of doing some of the things that I am about to mention.

The reason why I am stating these points is not to badmouth or put down people who are doing these things. 

No, it is to build up people to become better problem solvers. And also drag people out of the pit of mediocrity when they can be so much more. I want people to be able to maximize their problem solving potential to its fullest.

Okay, now lets (gulp) go through the list point by point.

I will be explaining why these items are downright destructive.

If you wish to examine problem solving techniques, please feel free to jump right ahead to section three. 

However, I recommend that you read through the "bad" ways of solving problems. Understanding what makes an approach bad will help you understand what makes a good approach/step towards solving a problem​.

2.1 Copying and Pasting Solutions 

Before I go on, let me tell you: I am also guilty of copying and pasting solution from stackoverflow or some other site.

Easy fix right? Just need to press ctrl c + v and the problem is solved. What is the harm in that? 

While you will most likely not be sued for breaching copyright laws, you are robbing somebody. And no, it is not the person who wrote the solution.

You are robbing yourself!​

Let that sink in for a bit. I am not here to condemn anyone. Mentioned this before but I will say it again. I, also, have also done this a countless number of times shamelessly. No need to feel ashamed. Get all that feelings of guilt out of your system before reading on. It doesn't do anyone good. 

Okay, now that we got all that guilt out of our system, the reason why copying and pasting results in robbery is that you are robbing yourself of a great opportunity to exercise your problem solving skills and grow.

Copying and pasting solutions is the greatest adversary to a programmers growth.

Click to Tweet

Without challenge, there is no growth. Your brain only grows when it is used. Do you learn how to solve problems better by copying and pasting what others did? 

Continue to copy and paste solutions, your brain is eventually going to erode to the point where even relatively simple problems will begin to stump you. Google does not have the answer to all the problems. 

If you want to become a better problem solver, cut this destructive habit out of your life today!

The only time you should copy and paste a solution is in order to try and understand the logic and thought process behind the copied code snippet.

2.2 Writing Code / Solving Problems on Auto Pilot

Everybody has done this at some point in their lives, regardless of vocation. I admit that I sometimes do this even on a weekly basis. 

Why do we go into auto-pilot mode? Let me propose to you a list of possible reasons.

  • We just want to get this (whatever it is) over and done with. Why?
    • Possibly due to a lack of interest/boredom.
    • Fatigue
    • Laziness
  • Don't want to use your brain.
    • Problem is too challenging
    • Distractions (Facebook, Video Games or anything that takes your mind off the problem at hand).

We go into auto pilot mode in our day to day activities because the task at hand is either so simple that our mind does not need to pay attention to it. Or, we just don't care about investing our mind and sincere effort into it. That is the harsh truth.

What is the root cause of this destructive mode of our mid? At the root of all the aforementioned possibilities is a lack of motivation.​

Therefore, go and find out what is sapping all your motivation! 

Trying to solve a problem on auto pilot is like drunk driving. You will crash and burn!

Click to Tweet

Why Is Auto Pilot Mode an Impediment to Effective Problem Solving?

Why is drunk driving unsafe?​

How come cutting vegetables while watching TV dangerous?

Why is doing homework while watching a movie unproductive? 

The answer is simple: because your mind is either elsewhere or divided.

If your mind is elsewhere, unless the problem is ridiculously simple, things are not going to turn out well.

2.3 Settling Down on the First Solution

Settling down on the first solution is very tempting, especially if things are are very busy and fast paced at your job. 

This approach will work, so why not just go with this method?

Let me tell you something: there is a saying that hindsight is 20/20.

Tunnel vision is also very real. As humans, we gravitate towards instant gratification and comfort. ​

For example, imagine for the sorting algorithms, we just decided on the fact that the bubble sort algorithm was the best and quickest approach to sorting items in a list. ​

If we just settled down on bubble sort, we would not have the merge sort or the quick sort algorithm

After solving a problem, aim to make your solution even better! A great example of iteratively improving a solution is Jetbrain's flagship IDE, Intellij IDEA, which they have developed and improved over many years. 

If Jetbrains stopped after the release of V1, I for one, would not be forking out money to use this IDE, especially when there are free open source alternatives such as Eclipse.​

After running through the problem once, your knowledge and understanding of the problem will definitely have increased in comparison to when you first tackled the problem.

Some things you can do to improve your solution include​ (but are not limited to)

  • Resolving pain points in the previous solution
  • Improve the algorithmic run-time of the current solution
  • Improve the readability of the code.
  • Incorporate new ideas from users of your solution and/or your own idea or that of co-workers into the solution.

2.4 Section Summary

​We have gone through a list of bad approaches to problem solving. Go through and ask yourself the following questions.

  • Am I copying and pasting solutions without thinking too much about the problem solving process?
  • Do I often solve problems while in auto pilot mode?
  • Do I have a tendency to picking and sticking with the first solution that comes to mind?

3. Ways to Become a Better Problem Solver

In this section, we will explore some good approaches to build up your problem solving skills. I put a fair bit of thought to this, so I really do hope that it helps you. Please let me know via a comment if this approach helped you.

However, do not expect results if you are not willing to put in the hard work.

​At the same time, I also want to encourage you by saying that all your hard work will not go unrewarded.

You will reap the results of the hard work at later stages of your life as a programmer. 

Therefore, rejoice in the trials and hardships. Persevere! In due time, you will reap the rewards!​

Before we go on, let me establish what I believe is one of the most crucial but often omitted point when people give advice to improve problem solving skills. I think one of the reasons is because it seems like pretty obvious advice.

However, since it is always omitted, people always overlook this point. So I am going to put it on blast for a moment.​

Great problem solvers process information thoroughly

Click to Tweet

Let me give an extreme example of not processing information.

Ever heard the saying "go in through one ear and out the other"? That is a perfect example of not processing the information. ​

On the other hand, an example of good, thorough processing can be seen​ through the sample coding/engineering interview at google.

Remember there are also frameworks for solving problems, such as design thinking​. When solving problems, remember that there is no such thing as one size fits all. The more experience you have, the better.

You will be able to refer to past experiences, identify patterns, which allows you to skip some steps in reaching an ideal solution. Ultimately, your ability to solve problems will be determined by the following (not limited to) factors

  • Information Processing Skills.
  • Decision making skills.
  • Analytical skills.

3.1 Extract Your Thoughts and Realize

When you are explicitly externalizing your thoughts or recently acquired information, you are processing it in your brain.

One of the reasons why I blog is to process my thoughts and solidify my understanding. 

I have tried it many times and let me tell you: it works. At least for me. If writing out the logic does not work, try something else that will enable you to extract your thoughts from your brain and bring it into the real world

Thoughts that remain locked up in your brain are not going to last long. FYI, an average person thinks approximately 50,000 thoughts a day.

What makes you think that the particular spark of inspiration will last in your brain forever unless you find a way to bring your thoughts into the real world by writing it out or through some other means?

There, you have it. One good example of getting your thoughts out of your brain is writing it down.

Want another example?

If you are one of those artistic types, try drawing or creating an art piece that leaves a lasting impression of your thought process or spark of inspiration.​

How about a flow chart? ​

As you can see, there are ​tonnes of options to extract your thoughts from your brain and realizing it.

As individuals, we all process differently. Therefore, there is no such thing as a cookie cutter method. 

Thus, it is important to go out of your comfort zone and experiment to find a list of ways that best suit you as an individual.

Extracting your Thoughts - Case Study

​In this example, I am going to refer to the merging logic in the merge sort algorithm. Let me summarize the scenario.

Objective: Compare the contents in two arrays and store the results in another array so that the items are inserted in ascending order. Return the results.

Assumptions:

  • The contents of the two arrays are sorted in ascending order.
  • We do not have to check the list for any non-number or invalid inputs.
  • We have access to the List interface, which enables us to easily check whether a list is empty and remove items from the start of the list.

Lets suppose we have a function called merge(), which accepts two parameters: the left list, which contains the first half of the list and the right list, containing the second half of the list. 

We need to sort and store the sorted results in a single list.

Since the two lists are sorted, we just need to keep an index counter that keeps track of indexes and compare the items in the two list with each other.​ The behavior will be something like this.

In most real world problems, we have to update our solution, due to the following (but not limited to) reasons.

  • Client decides that the current approach does not fully satisfy his/her needs.
  • Unforeseen variable (changes in work scope or introduction of new systems or procedures that affect your work).

A problem is not a problem if we can CTRL C + V our way to the answer.

Click to Tweet

The one constant that you can rely on in software engineering and problem solving is the lovely variable that we all adore: change

Being Able to Adapt to Changes is a Mark of a Great Problem Solver

Suppose for some reason, we are not allowed to use the built in list and we have to rely on primitive arrays. That means the third assumption from the previous section no longer holds.

That is a monkeys wrench in our plans right? Well, for a good problem solver, albeit it is a setback, it is nothing to cry over. 

Since we can't pop data off in an array (unless you are writing code in JavaScript), what do we do? 

We have to re-calibrate our assumptions. 

One of the operations we assumed we could do easily, is now no longer available to us. Broadly speaking, we are faced with two possible options in this example.


1. Build up the logic that enables us to check if an array is empty and remove items from the front of the list (including the logic for reducing the size).

2. Find another way/logic of handling the merging feature without removing items from the front of the list and plugging it into the result.


Critically Assess your options

When we are looking at a problem, we need to first understand the requirements of the user and have the right idea of what the desired outcome is.

Why do people like the merge sort algorithm? Because it is stable and its reliable search time of O (n log n).

With that in mind, lets put on our thinking caps and examine the two options.


If you know a thing or two about arrays, you will know that arrays are NOT dynamic data structures.

Therefore, in order to remove an element from an array, we need to reconstruct a new array with n - 1 elements. Afterwards, we need to add the elements one by one into the new array. That is O(n) in both time and space complexity for removing a single element. 

Furthermore, we need to do this each time an element is removed. FYI, since this remove logic is inside a for loop, it will execute n times.

As a result, the operation for merging will ramp up to O(n ^ 2). The merge sort will no longer be the O (n log n) merge sort we are aiming for.​

With that in mind, option one doesn't seem like such a good idea. ​

Therefore, seems like option two is more viable than one. We would need to organize this information, possibly writing out the time and space complexity of both approaches.

How you organize the information and assumptions will impact how you view the problem. If written well, it may spark a light for an even better solution! Sounds important right? ​

please note that this is not a do once only action item.

The art of problem solving is an iterative activity.

As new information is made available, the options have to be weighed and assessed for the reasons that we discussed in previous sections. 

In the next section, we will examine the importance of organizing the information in a cohesive and expressive manner.

3.2 Organize the Acquired Information and Thoughts

​It is NOT enough for us to simply extract the information and thoughts out of our brain. That is merely the first step.

Great problem solvers organize the information.

You might be wondering: What does organizing the information achieve?​

Organizing information enables viewers to see the problem from multiple angles.

Click to Tweet

How you organize the information that you absorb and process will drastically impact your ability to see the problem clearly, and thus, your ability to come up with the appropriate solutions.

How to Organize Information

There is no absolute right or wrong answers, because we all process and absorb information differently. 

Once again, I will remind you that in order to solve a problem cleanly, we need to understand and know the problem.

One great way ​to get to know a problem is to organize information so that we can view the problem from multiple angles. 

For example, unless I have a clear view of the phone from the front and the back, I ​can't tell if I am looking at a galaxy S 8 or a Note 6. If you only look at it from the side, you will miss out on a lot of information about the phone's appearance.

First step is to ascertain what information we would need in order to achieve the same functionality with an array. After pondering, we come to the conclusion that we need the following information.

  1. The index of the result Array. Why? Because we need to allocate data in the right indexes of the array. 
  2. The current index of the left array. As we add items from it, we increment the index. 
  3. The current index of the right array. Same reason as above. 

The next step when dealing with problems is to analyze possible scenarios and undesirable cases

  1. What happens if the index of the left or right array exceeds the actual length of the array. Wait, is this even possible? Yes, it is possible and our program will yield an error if not handled. 
  2. After I iterate through the list, what do I have to do to finish up? How many possible situations are there. What do they look like? How do I handle them?

The questions above are some examples of questions you can ask to analyze and identify these undesirable cases.

Do you see the pattern? In case you missed it or you are pondering something, let me make it as clear as the day.

Great programmers are able to effectively gather and organize their thoughts.

Click to Tweet

Good Approaches to Organizing Information?

Before I give you a list, let me set this straight. By now, you are probably sick of hearing this over and over again, but I need to drill this in.

The reason being I want you, as a reader, to do some work and searching of your own to find your own style/approach to solving problems. Otherwise, you will never reach your peak and that would SERIOUSLY be wasteful :(.​

There is no such thing as a cookie cutter solution for organizing information. 

Each individual thinks and processes information differently. EXPERIMENT! Pick the methods that best suit you. Of course, when you are sharing this information with others, be sure to communicate in a manner that can be understood effectively by a wide range of audiences. 

Below are some good examples of organizing information

This is where you have to experiment. Try as many approaches as possible and identify which methods suit you the most for a particular type of problem.

Yes, depending on the nature of the problem, how you document or organize the information and your thoughts can vary. That is, if you really want to be efficient.

Information, list of variables and potential threats can span endlessly unless we have the right assumptions placed. This is why making the right assumptions is so crucial for programming. Imagine having to do validation checks on each and every single number. The algorithm time complexity will go out of whack. 

Literally for every problem with a reasonable degree of difficulty, the solutions will not be clear at first. This is when your problem solving skills will make the difference between solving the problem successfully and running around for hours aimlessly like a headless chicken.​

Get into a habit of writing down and organizing your train of thoughts. It will build you up into a better problem solver, and ultimately, a better programmer.​

3.3 Pick the Brains of Other Engineers

Unless you are Elbert Einstein, you aren't going to be able to think of the most optimal solution for every single problem that you come across. 

The ability to pull knowledge from others is a crucial skill. 

As programmers, or as humans, we are limited by our pool of knowledge, derived from our experiences. Combine two heads, you have two entirely separate pools of knowledge. This benefits the other party as well, so there is absolutely no reason to not team up!

What are some Good Questions to Ask?

While good questions differ case by case, below is a list of general questions that will put you facing the right direction.

If you would like to see questions added onto the list, please leave a comment and let me know. I plan on keeping this post updated.​

1. I like the way you did <insert action>. How did you decide to take that approach?

2. Can you walk me through the your thought process in coming to that conclusion?

3.4 Be Intentional and Fully Present When Solving Problems

No matter how many articles you read or what else you do, it won't matter if you are not intentional about actually solving the problem.

Whether you are on auto pilot mode or you are actually trying to solve the problem, you will most likely write code. 

The difference between being intentional and going on auto pilot is the route that you take when solving the problem. 

Intentional people ask well thought out questions. They will draw diagrams, read up on articles, digest the knowledge and fully understand the problem at hand before tackling it.

Problems are problems because they are somewhat challenging. ​A problem wouldn't even be a problem in the first place, if it was a piece of cake.

Therefore, problems require your full, undivided attention. Being fully present enables you to pour as much mental resources as possible towards solving the problem at hand. It is a requirement for those who are serious about improving their problem solving skills.

People running on auto pilot on the other hand, will immediately jump the gun and start writing code after just asking one or two questions.

They may get the desired output, but chances are, the code will most likely not be as structured, and may be error prone and brittle. A little wind may possibly blow down the entire house.  

Learn to master yourself.

Stop yourself from tabbing onto Facebook or Instagram. ​Use techniques such as the pomodoro technique to be fully present and engaged in solving the problem at hand.

You may have to learn new skills if the problem is quite challenging. Make sure you don't fall into any pitfalls, traps or mistakes when learning.

3.5 Section Summary

So, If I were to summarize all the information listed in the information above, users should get used to doing the following

  • Gathering information and listing all assumptions. 
  • With the information gathered, writing out a logical solution.
  • Organizing the solution/logic cohesively into pseudo code.
  • Pick the brains of other programmers and engineers to flesh out your ideas.
  • If the logic is complex, organizing the steps and procedures coherently into an activity diagram. 
  • Always be conscious of whether you are auto piloting or being intentional with solving the problem.

4. Words of Advice

Okay, that was a lengthy and fairly intense post. 

The heart of this post is that in order to become a good problem solver, you first need to start by accepting the fact that each problem is unique

There is a saying that familiarity breeds contempt. A great recipe for flipping on the auto pilot switch. Say bye bye to problem solving skills!​

After ensuring that you are not adopting the worst ways of approaching a problem, we need to be intentional with the problem and handle the information effectively to see the problem from multiple angles.

Accurate information coupled with precise assumptions enable us to craft effective, robust and specialized solutions that deliver great performance for tackling a specific problem.​

Ending on a slightly lighter note, if this article helped you, please share this article. Hopefully those that come across it will find the contents enlightening. 

Please also send feedback, suggestions and words of advice if you have any. 

Remember that we are all journeying together in becoming better problem solvers. Share the knowledge and help those around you.

Hope that this article helped you out a lot.

And until next time, peace!

About the Author Jay

I am a programmer currently living in Seoul, South Korea. I created this blog as an outlet to express what I know / have been learning in text form for retaining knowledge and also to hopefully help the wider community. I am passionate about data structures and algorithms. The back-end and databases is where my heart is at.

follow me on:
28 Shares