How to Develop Algorithmic Thinking in DSA?

Algorithmic Thinking has recently become a buzzword among programmers. It is a method for solving problems based on a clear definition of steps: logically and repeatedly. This could help us understand several problem-solving strategies.

In programming, two skills are critical to solving a coding problem: 1) Identifying and designing an efficient solution approach and 2) Converting the solution approach into a correct code. Some programmers face challenges developing the first skill, which requires algorithmic thinking. On another side, sometimes interviewers offering problems during interviews claim that they are more interested in how an interviewee approaches a problem than the implementation of the solution. Showing expertise in algorithmic thinking and applying problem-solving strategies can be an attractive way to impress a potential employer.

The critical question is: How do we develop algorithmic thinking independently from learning programming? There are several ways of it! Let's explore.

Algorithmic Thinking via Solving Puzzles

Solving algorithmic puzzles is a productive and enjoyable way to develop algorithmic thinking. This could help us think about a coding problem on a more abstract level. For example, we can learn several problem-solving strategies using puzzles:

  • Decrease and conquer (Josephus problem)
  • Divide and conquer (Finding a fake among eight coins)
  • Dynamic programming (Egg dropping puzzle)
  • Backtracking (8-queen puzzle)
  • Greedy approach (Fractional knapsack problem)
  • String manipulation (Fizz buzz problem)
  • Mathematical approach (The water jug puzzle)

Here are some more examples of such types of puzzles:

Puzzle based on the properties of numbers theory

Bulbs in a circle puzzle

Puzzle based on properties of graph

The Icosian game puzzle

Puzzle based on incremental approach

Rectangle disection puzzle

Puzzle based on graph-based transformation

Chessboard transformation puzzle

Puzzle based on dynamic programming

Finding maximum sum puzzle

Puzzle based on incremental approach

Square build up puzzle

Puzzle based on idea of backtracking

Eight queen on a chessboard puzzle

Puzzle based on iterative elimination

Finding celebrity puzzle

Puzzle based on properties of the graph

The Konigberg bridge puzzle

Puzzle based on idea of elimination

Single elimination tournament puzzle

Puzzle based on idea of transformation

Row and column exchange puzzle

Puzzle based on mathematical counting

Mental arithmatic puzzle

Here are some essential ideas related to solving algorithmic puzzles:

  • Every puzzle has an input that defines an instance of the puzzle. An instance can be either specific (e.g., find a false coin among eight coins with a balance) or general (e.g., find a false coin among N coins with a balance).
  • When dealing with specific instance of a puzzle, one must focus on the particular instance given. It might be the case that other instances of puzzle do not have same solution or even do not have solutions at all!
  • On other hand, solving the general instance of a puzzle could be more satisfying and even more comfortable most of the time.
  • Whether a puzzle is presented in its general form, it is always a good idea to solve few small instances of it anyway because it can provide valuable insights about the solution of general instance of the given puzzle.

Algorithmic Thinking via Practicing Steps of Problem-Solving

The solution to every problem has to go through well-defined steps, and practicing these steps helps us save time and understand patterns among several coding problems.  

Step of problem-solving in data structure and algorithms

Step 1: Understanding the problem statement

We need to understand the problem by drawing a clear visualization. We should ask these critical questions: Do we know every word used within the problem? What data or information are provided as input? What data or results are requested as an output?

In addition to this, we need to understand computational and non-computational details relevant to the problem like data structures, specific constraints given on input, distribution of the input, etc.

Step 2: Selecting concepts and solution strategies based on experience

Based on problem description, we need to make predictions regarding concepts necessary to solve the problem. We should think: Are we going to use all information available in the problem? Is it possible to eliminate unnecessary information? Have we solved any similar problems in the past? If yes, then take advantage of that experience. Identifying approaches or concepts or already known algorithms for similar problems can help us save a lot of time.

Step 3: Formulation of a solution strategy and pseudocode

We should explore a hand-written way to solve problem by going through several examples and developing general step-by-step strategy. To do this, we need to carefully think about each step and observe what actions are common to every example. Two types of thinking are important at this stage:

We need to visualize solution steps on the paper by describing operations to transform the given input into the desired output. After this, we can move forward to write step-by-step solutions in simple English and Transform them into pseudocode or flowchart.

Step 4: Correct Programming Implementation

Now we can move forward to transform the pseudocode into a working code using our favorite programming languages like C++, Java, Python, etc. During this process, we need to select programming elements for efficient code implementation and simplify data handling: Solution function, helper functions, loop initialization and termination, base cases of recursive code, scope and initialization of local variables, global variables, memory allocation, and deallocation, pre-processing, pointers manipulations, etc. Note: Please take care of the correct coding style :)

Step 5: Verifying correctness and optimizing further

Now, we need to test the programming implementation for bugs, analyze time and space complexity, and think to optimize solution further. These ideas can work best at this stage:

  • Manually analyze the input-output pattern by performing a hand trace. If needed, draw a plot to describe the behavior of the variables or critical steps defined in the solution.
  • We need to identify some input for which our algorithm does not provide the correct output. If there is an error or bug, identify and correct the steps responsible for that bug. At the end of the process, our solution must handle all boundary cases.
  • After verifying correctness, now we should analyze the efficiency by counting the total number of operations with respect to the input size.
  • Now the critical step is to optimize the solution and solve it using a fewer number of steps. But how do we do it? We can identify some essential details of the problem and try a different problem-solving approach. We should keep optimizing the solution further until there is no further possibility.
  • Sometimes we can also optimize the solution code further by reducing some intermediate steps in the pseudocode.

Here are some popular coding questions to practice the steps of problem-solving. These questions can be solved using four or more approaches.

Algorithmic Thinking via Understanding Real-life Applications

In our surroundings, many applications are using efficient problem-solving strategies to deliver the best user experience and performance. Understanding the idea behind such a strategy is a defining step in developing algorithmic thinking. For example:

  • Caching strategy: LRU and LFU cache
  • Scheduling strategy: Round-robin scheduling, Priority scheduling.
  • Hashing strategy: Hash-based load balancing, Encrypting data in cryptography, Symbol table in a compiler, Spelling check.
  • Sorting strategy: Comparison-based sorting, linear time sorting.

Enjoy learning, Enjoy thinking!

Share feedback with us

More blogs to explore

Our weekly newsletter

Subscribe to get weekly content on data structure and algorithms, machine learning, system design and oops.

© 2022 Code Algorithms Pvt. Ltd.

All rights reserved.