DSA Tutorial
šŸ”

What is an Algorithm?

You follow algorithms every single day without realizing it.

When you make tea, you follow a sequence of precise steps: boil water, add tea leaves, wait, strain, pour into a cup. Skip a step, do them out of order, or wait too long — and the result changes completely.

That sequence of ordered, unambiguous steps is an algorithm.

In programming, an algorithm is a finite set of well-defined instructions that takes some input, processes it through a sequence of steps, and produces a correct output. It is the recipe that your program follows to solve a problem.

The key word is well-defined. Every step must be clear and executable. "Sort this list somehow" is not an algorithm. "Compare adjacent elements and swap them if the left one is greater than the right one, repeat until no swaps occur" — that is an algorithm (Bubble Sort).

Why Algorithms Matter

Data structures organize your data. Algorithms decide what you do with it.

You can have the most perfectly organized data in the world, but without the right algorithm, you still cannot extract value from it efficiently. A phone book sorted alphabetically (a data structure decision) only becomes useful when you search it with binary search instead of reading every page (an algorithm decision).

The combination of the right data structure and the right algorithm is what separates software that scales from software that collapses under load.

When Google returns search results in 200 milliseconds across billions of web pages, that is algorithms working. When Spotify builds a playlist that fits your mood, that is algorithms. When your GPS reroutes around traffic in real time, that is algorithms.

In interviews, algorithm questions test whether you can think about problems systematically — not whether you have memorized solutions. That is the real goal of this entire series.

Properties of a Good Algorithm

Not every sequence of steps qualifies as a valid algorithm. A well-designed algorithm must satisfy five properties:

  1. ›Finiteness — It must terminate after a finite number of steps. An algorithm that runs forever solves nothing.
  2. ›Definiteness — Every step must be clear and unambiguous. There is no room for interpretation.
  3. ›Input — It takes zero or more inputs. Some algorithms need input (sorting needs a list). Some need none (generating the first 10 Fibonacci numbers).
  4. ›Output — It produces at least one output — the result of solving the problem.
  5. ›Effectiveness — Every step must be basic enough to be carried out exactly and in a finite amount of time.

These five properties distinguish a real algorithm from a vague idea.

Algorithm vs Data Structure

This is one of the most common points of confusion for beginners. Here is the clear distinction:

AspectData StructureAlgorithm
DefinitionHow data is organized and storedStep-by-step instructions to solve a problem
RoleContainer for dataProcess that operates on data
ExampleArray, Tree, Hash MapBinary Search, Merge Sort, BFS
Stores stateYesNo — it executes logic
DependencyNeeds algorithms to be usefulNeeds data structures to operate on

Think of it this way: a data structure is the kitchen. An algorithm is the recipe. You need both to cook a meal.

How to Represent an Algorithm

Before writing code, experienced developers think through an algorithm in abstract form. There are three common representations.

Natural Language

Describe the steps in plain English. Useful for initial thinking but imprecise.

To find the largest number in a list:
1. Assume the first number is the largest.
2. Compare each remaining number to the current largest.
3. If a number is bigger, update the largest.
4. After all comparisons, return the largest.

Pseudocode

A structured, language-independent way to express logic. More precise than English, not tied to any syntax.

function findMax(arr):
    max = arr[0]
    for each element in arr:
        if element > max:
            max = element
    return max

Code

The actual implementation in a programming language. This is where logic becomes executable.

For most of this course, pseudocode and actual code will be the primary representations. Understanding pseudocode is a critical interview skill — interviewers often want you to explain your approach clearly before you write a single line.

Your First Algorithm: Finding the Maximum

The problem: given a list of numbers, find the largest one.

Before writing code, think through the approach:

  • ›Start by assuming the first element is the maximum
  • ›Walk through every remaining element one by one
  • ›If any element is larger than the current maximum, update the maximum
  • ›After the full list is scanned, the maximum holds the answer

This is a linear scan — one of the most fundamental algorithmic patterns. Every element is visited exactly once, so the work grows proportionally with the input size.

1public class FindMaximum { 2 3 // Returns the largest value in the array 4 public static int findMax(int[] arr) { 5 // Start by assuming the first element is the maximum 6 int max = arr[0]; 7 8 // Compare every remaining element against the current maximum 9 for (int i = 1; i < arr.length; i++) { 10 if (arr[i] > max) { 11 // Found a new maximum — update it 12 max = arr[i]; 13 } 14 } 15 16 return max; 17 } 18 19 public static void main(String[] args) { 20 int[] numbers = {34, 7, 23, 32, 5, 62, 15}; 21 int result = findMax(numbers); 22 System.out.println("Largest number: " + result); 23 } 24}
Output:
Largest number: 62

Dry Run: Step by Step

Let us walk through exactly what happens when findMax runs on [34, 7, 23, 32, 5, 62, 15].

Input: [34, 7, 23, 32, 5, 62, 15]

Start: max = 34          (assume first element is max)

i=1  → arr[1] = 7    → 7  > 34? No  → max stays 34
i=2  → arr[2] = 23   → 23 > 34? No  → max stays 34
i=3  → arr[3] = 32   → 32 > 34? No  → max stays 34
i=4  → arr[4] = 5    → 5  > 34? No  → max stays 34
i=5  → arr[5] = 62   → 62 > 34? Yes → max = 62
i=6  → arr[6] = 15   → 15 > 62? No  → max stays 62

Result: 62

Every element is visited exactly once. When 62 is encountered at index 5, the maximum updates. No previous comparison is repeated. This clean, single-pass behavior is what makes the algorithm efficient.

How Algorithms Are Evaluated

Two questions always matter when evaluating an algorithm:

How fast does it run? This is time complexity — how the number of operations grows as input size increases.

How much memory does it use? This is space complexity — how memory usage grows with input size.

For findMax, the answer is clean:

MetricValueReason
Time ComplexityO(n)Every element is visited exactly once
Space ComplexityO(1)Only one extra variable (max) is used

These topics get full dedicated sections next in this series. For now, remember: a correct algorithm is not always a good algorithm. A correct solution that runs in O(n) is almost always better than a correct solution that runs in O(n²) for large inputs.

Brute Force vs Optimized Thinking

Every algorithm problem has at least two layers.

Brute Force — the most obvious solution. Usually correct but slow. Always a valid starting point.

Optimized — a solution that improves on brute force using a clever observation, a better data structure, or a known pattern.

The progression from brute force to optimized is the core interview skill. Interviewers do not just want the optimal answer — they want to see how you reason toward it.

For findMax, brute force and optimized look identical because the problem is inherently linear. You cannot find the maximum without looking at every element at least once. No optimization exists beyond O(n).

But consider a sorted array. If you want to find the maximum in a sorted array, scanning the whole thing is unnecessary. The maximum is the last element — O(1). Recognizing what the input structure tells you is what separates strong problem-solving from mechanical coding.

Types of Algorithms

Algorithms fall into recognizable categories. Learning to identify which category a problem belongs to is one of the most valuable skills in interview preparation.

CategoryCore IdeaExample Problems
Brute ForceTry all possibilitiesFinding duplicates by checking every pair
Divide and ConquerBreak the problem, solve parts, combineMerge Sort, Binary Search
GreedyMake the locally best choice at each stepActivity Selection, Huffman Encoding
Dynamic ProgrammingCache results of overlapping subproblemsFibonacci, Knapsack, LCS
BacktrackingExplore all paths, undo when stuckN-Queens, Sudoku Solver
Graph TraversalVisit nodes systematicallyBFS, DFS, Dijkstra's Algorithm
Two PointersUse two indices to reduce nested loopsPair Sum, Remove Duplicates
Sliding WindowMaintain a moving subarray windowMaximum Subarray, Longest Substring

You will encounter every one of these throughout this course. The goal is not memorizing the list — it is learning to recognize which category fits a problem when you see it.

How Experienced Developers Think About Algorithms

When a senior developer sees a new problem, they do not immediately write code. They work through a mental checklist:

What is the input? What type, what size, what constraints? Can it be empty? Can values repeat?

What is the output? What does a correct answer look like? Is it a single value, a list, a yes or no?

What is the obvious approach? Even if slow, start with what works.

What is the bottleneck? Which part of the brute force is doing the most unnecessary work?

What structure exists in the problem? Is the input sorted? Are there repeated subproblems? Can memory be traded for speed?

What pattern does this resemble? Have I solved something similar before?

This systematic thinking is what this entire course is building. By the time you reach Dynamic Programming and Graphs, this mental process should feel automatic.

Edge Cases Every Algorithm Must Handle

A common beginner mistake is writing an algorithm that works for the normal case but breaks on unusual inputs. For findMax, the important edge cases are:

  • ›Empty array — there is no maximum. The algorithm must check for this before starting, otherwise arr[0] crashes.
  • ›Single element — the only element is trivially the maximum. The loop never executes, and the initial assumption is immediately correct.
  • ›All identical elements — every comparison fails (not strictly greater), and the first element is correctly returned as the maximum.
  • ›All negative numbers — the algorithm still works correctly because it compares values, not signs.
  • ›Already sorted in descending order — the maximum is at index 0. The initial assumption is correct and never changes.

Notice that the single-element, all-identical, and descending-sorted cases are handled correctly by the implementation without any extra code. That is a sign of a well-designed algorithm — it handles edge cases naturally through its core logic.

Real-World Algorithms in Production

Every piece of software you use runs on algorithms solving real problems at scale.

  • ›Recommendation systems — Netflix and YouTube use collaborative filtering algorithms to predict what you will watch next based on behavior patterns
  • ›Search engines — PageRank, Google's foundational algorithm, ranks web pages by analyzing link structures across billions of pages
  • ›Routing — GPS navigation uses Dijkstra's shortest-path algorithm to find the fastest route in real time
  • ›Compression — ZIP files use Huffman Encoding, a greedy algorithm, to reduce file size without losing data
  • ›Databases — query optimizers use algorithms to choose the cheapest execution plan for your SQL queries automatically

Every time you tap "Get Directions," stream a video, or search for something, you are benefiting from decades of algorithmic research turned into production code.

Common Mistakes Beginners Make

Starting with code before thinking. Writing code before understanding the problem leads to solutions that sort of work but miss edge cases or use entirely the wrong approach. Think first — pseudocode or plain English — then code.

Assuming brute force is wrong. Brute force is a valid starting point. A working O(n²) solution you can explain and reason about is better than a half-written O(n log n) solution you do not understand. Start simple, then optimize.

Not validating input. Real algorithms must handle edge cases. Empty arrays, null inputs, single elements — these appear in both interviews and production. Always ask: what happens if the input is empty?

Confusing correctness with efficiency. An algorithm can be completely correct and completely unusable at scale. A sorting algorithm that works on 10 elements but takes billions of steps on 100,000 elements is correct but impractical.

Giving up when stuck. Algorithm thinking is a skill built through practice, not talent. Every problem you get stuck on and eventually solve builds the intuition you will use automatically later.

Interview Questions

Q: What is an algorithm, and what are its five properties?

An algorithm is a finite, well-defined sequence of instructions that takes input and produces output to solve a specific problem. Its five properties are finiteness (must terminate), definiteness (each step is unambiguous), input (zero or more inputs accepted), output (at least one output produced), and effectiveness (every step is basic and executable in finite time).

Q: What is the difference between time complexity and space complexity?

Time complexity measures how the number of operations grows as input size increases. Space complexity measures how memory usage grows. Both are expressed using Big-O notation. Real-world decisions often involve trading one for the other — for example, caching intermediate results uses more memory but reduces repeated computation.

Q: How do you approach a new algorithm problem in an interview?

Start by understanding the problem clearly — repeat it in your own words. Clarify input format, output format, and constraints. Work through a small example by hand. Identify the brute force approach first. Then analyze its bottleneck and reason toward an optimization. Communicate your thinking aloud throughout — interviewers care about your reasoning process as much as your final answer.

Q: Can the same problem have multiple correct algorithms?

Yes, and this is common. Sorting alone has dozens of correct algorithms — Bubble Sort, Merge Sort, Quick Sort, Heap Sort — all producing the same output but with very different time and space complexity tradeoffs. The right algorithm depends on the problem constraints, input size, and environment.

FAQs

Do I need to invent new algorithms to be a good developer?

No. The vast majority of software development involves selecting and applying well-known algorithms to new problems. Understanding the standard algorithms deeply — why they work, when to use them, what their tradeoffs are — is far more valuable than inventing novel ones.

How is pseudocode different from real code?

Pseudocode describes the logic of an algorithm without worrying about language-specific syntax. It uses structured logic (if, for, while, return) but in plain language. It does not compile or run — it is a thinking and communication tool used to plan before coding.

Will I need to memorize all these algorithms?

You will need to recognize common patterns and implement standard algorithms from scratch in interviews. But the goal is deep understanding, not memorization. Understanding why Merge Sort is O(n log n) helps you reconstruct it under pressure far better than memorizing the code line by line.

How long does it take to get good at algorithms?

Most developers see significant improvement after solving 50 to 100 problems across different categories with genuine understanding — not just reading solutions. Consistent daily practice over two to three months is far more effective than cramming before an interview.

Quick Quiz

Question 1: Which property of an algorithm ensures it will eventually stop running?

  • ›A) Definiteness
  • ›B) Effectiveness
  • ›C) Finiteness
  • ›D) Output

Answer: C) Finiteness. An algorithm must terminate after a finite number of steps. An infinite loop violates this property and disqualifies the process from being a valid algorithm.

Question 2: What is the time complexity of the findMax algorithm?

  • ›A) O(1)
  • ›B) O(log n)
  • ›C) O(n log n)
  • ›D) O(n)

Answer: D) O(n). Every element in the array is visited exactly once. As the input grows by n elements, the work grows proportionally — one comparison per element.

Question 3: What should you do first when encountering a new algorithm problem?

  • ›A) Write the optimized solution immediately
  • ›B) Start coding in your strongest language
  • ›C) Understand the problem and identify a brute force approach
  • ›D) Search for a known algorithm that matches

Answer: C) Understand the problem and identify a brute force approach. Understanding the problem deeply and starting with brute force is the foundation of strong algorithm thinking. Optimization follows understanding — never the other way around.

Summary

An algorithm is a finite, well-defined sequence of steps that transforms input into output to solve a specific problem. It is the process that operates on your data structures to produce results.

The key ideas to carry forward:

  • ›Algorithms are precise — every step must be clear and unambiguous
  • ›Data structures and algorithms are partners — neither is fully useful without the other
  • ›Every algorithm is evaluated on time complexity and space complexity
  • ›Brute force first, optimization second — this is the correct thinking order
  • ›Edge cases are not optional — every algorithm must handle unusual inputs explicitly
  • ›Pattern recognition is the core interview skill — learning to classify problems by category

In the next topic, you will explore Time Complexity (Big-O) — learning the formal language for measuring and comparing how efficiently algorithms run as input grows.