logo
Icon

Greedy Algorithms: Examples, Types, Complexity

5 mins read

Last updated: 11 Feb 2025

5049 views

0%

  • Introduction
  • What is Greedy Algorithm?
  • Understanding Greedy Algorithm With Real-life Example
  • Components of Greedy Algorithm
  • How Greedy Algorithms Work?
  • Greedy Algorithms Examples
  • Types of Greedy Algorithms
  • Time Complexity of Greedy Algorithms
  • Space Complexity of Greedy Algorithms
  • Applications of Greedy Algorithms
  • Advantages of Greedy Algorithms
  • Disadvantages of Greedy Algorithms

Introduction

A greedy algorithm is a problem-solving approach that makes the best possible choice at each step to achieve a solution. The idea is to choose the option that looks best at the moment, without worrying about the overall problem. 

Let’s learn everything about greedy algorithms in data structure, including examples, types, working, time and space complexity, applications, and more.

What is Greedy Algorithm?

A greedy algorithm is a way to solve problems by making the best choice that seems right at each step, without thinking about the future. It focuses on taking the most immediate, obvious solution that looks like it will work best right now. This approach doesn’t worry about whether the decision will be perfect in the long run, just that it’s the best option at the moment.

Understanding Greedy Algorithm With Real-life Example

Imagine you are hungry and want to eat something. You walk into a store with different food options. You have only a few coins with you, and you want to get the most food for your money. 

A greedy approach would be to look at all the food, pick the one that gives you the most for your coins, buy it, and then repeat with the coins you have left. You’re not planning ahead for what you might want later, just grabbing the best deal you see right now.

In some cases, this approach works perfectly and gives you the best possible outcome. In other cases, it might not give you the best overall result, but it’s a quick and easy way to solve the problem. Greedy algorithms are like this—they work by making decisions that seem best in the moment, which can lead to a good solution quickly and easily.

Components of Greedy Algorithm

1. Greedy Choice Property

This property means that a greedy algorithm always makes the choice that seems the best at the moment. It selects the option that offers the most immediate benefit without considering the future consequences. 

The idea is that by choosing the best local option at each step, the algorithm will eventually reach an optimal solution for the entire problem.

2. Optimal Substructure

Optimal substructure refers to the idea that a problem can be broken down into smaller subproblems, and the optimal solution to the overall problem can be achieved by solving these subproblems optimally. 

In other words, if you solve each small part of the problem in the best possible way, you can combine these solutions to get the best solution for the whole problem. This is a key characteristic that allows greedy algorithms to work effectively.

How Greedy Algorithms Work?

Greedy algorithms solve problems by following a simple, step-by-step approach:

1. Identify the Problem: The first step is to understand the problem and determine that it can be solved using a greedy approach. This usually involves recognizing that the problem can be broken down into a series of decisions.

2. Make the Greedy Choice: At each step of the problem, the algorithm makes the best choice that seems optimal at the moment. This choice is made based on the greedy choice property, which means selecting the option that offers the most immediate benefit.

3. Solve the Subproblems: After making a greedy choice, the problem is reduced to a smaller subproblem. The algorithm then repeats the process—making another greedy choice for the smaller problem.

4. Combine the Solutions: The algorithm continues making greedy choices and solving subproblems until the entire problem is solved. The solution to the overall problem is simply the combination of all the greedy choices made at each step.

Greedy Algorithms Examples

Below are some examples of greedy algorithm:

1. Activity Selection Problem

The Activity Selection Problem involves selecting the maximum number of activities that don't overlap with each other, given their start and end times. The goal is to maximize the number of activities that can be attended.

Working:

  • Step 1: Sort the activities based on their finish times (earliest finish time first).

  • Step 2: Select the first activity (the one that finishes the earliest).

  • Step 3: For each subsequent activity, select it only if its start time is greater than or equal to the finish time of the last selected activity.

  • Step 4: Repeat until all activities have been considered.

Example:

Given activities with the following start and end times:

  • Activity 1: (1, 4)

  • Activity 2: (3, 5)

  • Activity 3: (0, 6)

  • Activity 4: (5, 7)

  • Activity 5: (8, 9)

The greedy choice would select Activity 1, then Activity 4, and finally Activity 5, as these do not overlap. The maximum number of non-overlapping activities is 3.

2. Huffman Coding

Huffman Coding is a method of data compression that assigns variable-length codes to input characters, with shorter codes assigned to more frequent characters. The goal is to minimize the total length of the encoded message.

Working:

  • Step 1: Count the frequency of each character in the input.

  • Step 2: Create a priority queue (min-heap) where each node represents a character and its frequency.

  • Step 3: Extract the two nodes with the lowest frequency from the queue.

  • Step 4: Create a new node with these two nodes as children and with a frequency equal to the sum of their frequencies.

  • Step 5: Insert this new node back into the queue.

  • Step 6: Repeat until only one node remains in the queue, which becomes the root of the Huffman Tree.

Example:

Consider the characters and their frequencies:

  • A: 5

  • B: 9

  • C: 12

  • D: 13

  • E: 16

  • F: 45

The greedy algorithm will build a Huffman Tree by repeatedly merging the two least frequent nodes until all characters are encoded, leading to an efficient prefix code where no code is a prefix of any other.

3. Prim’s Algorithm

Prim’s Algorithm is used to find the Minimum Spanning Tree (MST) of a connected, undirected graph. The MST is a subset of the edges that connects all vertices together without any cycles and with the minimum possible total edge weight.

Working:

  • Step 1: Start with any arbitrary vertex and add it to the MST.

  • Step 2: At each step, add the smallest edge that connects a vertex in the MST to a vertex outside the MST.

  • Step 3: Repeat until all vertices are included in the MST.

Example:

Consider a graph with the following vertices and edges:

  • Vertices: {A, B, C, D, E}

  • Edges with weights: (A-B, 1), (B-C, 4), (A-C, 3), (C-D, 2), (B-D, 5), (D-E, 1)

Prim’s algorithm would start at any vertex, say A, and select the edge with the smallest weight that connects to a new vertex, building the MST step by step. The resulting MST might include edges (A-B), (A-C), (C-D), and (D-E) with the total minimum weight.

Types of Greedy Algorithms

1. Fractional Greedy Algorithms

These algorithms work by making the best possible choice at each step based on fractions. They are typically used in problems where items can be divided into smaller parts.

Example: Fractional Knapsack Problem – where the goal is to maximize the total value in the knapsack by taking fractions of items if necessary.

2. Pure Greedy Algorithms

These algorithms make the best possible choice at each step without considering future consequences and without the possibility of revisiting previous decisions. Once a choice is made, it is final.

Example: Activity Selection Problem – where activities are selected based on their finish times to maximize the number of non-overlapping activities.

3. Recursive Greedy Algorithms:

These algorithms use recursion to make a series of greedy choices. The problem is divided into subproblems, and the algorithm makes a greedy choice and then recursively solves the subproblem.

Example: Prim’s Algorithm – which builds a minimum spanning tree by making the greedy choice of adding the smallest edge at each step and recursively continuing this process.

4. Greedy Choice Property Algorithms:

These algorithms rely on the greedy choice property, which ensures that a globally optimal solution can be reached by making locally optimal choices.

Example: Huffman Coding – where characters are assigned variable-length codes based on their frequencies, with the goal of minimizing the total length of the encoded message.

5. Adaptive Greedy Algorithms

These algorithms adapt their strategies based on the current state of the problem. They may reconsider previous decisions if necessary to improve the overall solution.

Example: Greedy Graph Coloring – where the algorithm assigns colors to the vertices of a graph, potentially adjusting choices as new vertices are colored.

6. Constructive Greedy Algorithms

These algorithms build the solution step by step by adding elements to the solution set based on a specific criterion.

Example: Kruskal’s Algorithm – which constructs a minimum spanning tree by adding the smallest edges that do not form a cycle.

7. Non-Adaptive Greedy Algorithms:

These algorithms make decisions that are final and do not adapt or change once a choice is made.

Example: Dijkstra’s Algorithm – which finds the shortest path from a source to all other vertices in a graph by making locally optimal choices at each step.

Time Complexity of Greedy Algorithms

The time complexity of common greedy algorithms is mostly O(n log n) or O(n).

Algorithm

Time Complexity

Activity Selection Problem

O(n log n)

Huffman Coding

O(n log n)

Fractional Knapsack Problem

O(n log n)

Coin Change Problem

O(n)

Job Sequencing with Deadlines

O(n log n)

Space Complexity of Greedy Algorithms

Algorithm

Space Complexity

Activity Selection Problem

O(1)

Huffman Coding

O(n)

Fractional Knapsack Problem

O(1)

Coin Change Problem

O(1)

Job Sequencing with Deadlines

O(n)

Applications of Greedy Algorithms

  • Network Routing: Greedy algorithms like Dijkstra’s algorithm are used to find the shortest path in network routing, optimizing data packet delivery across the internet.

  • Task Scheduling: Used in job sequencing problems to maximize profit or minimize deadlines by selecting jobs in order of priority.

  • Resource Allocation: Applied in scenarios like the fractional knapsack problem to allocate resources efficiently based on value-to-weight ratios.

  • Data Compression: Huffman coding uses a greedy approach to compress data efficiently by encoding frequently used characters with shorter codes.

  • Coin Change: A greedy approach is often used to provide the minimum number of coins for a given amount of money, particularly when the denominations are standard (like in most currencies).

  • Greedy Coloring: Applied in graph theory for problems like graph coloring, where the goal is to minimize the number of colors needed to color a graph while ensuring no two adjacent vertices share the same color.

  • Traveling Salesman Problem (TSP) Heuristic: Greedy heuristics are used in approximating solutions to the TSP by selecting the nearest unvisited city at each step.

Advantages of Greedy Algorithms

  • Simplicity: Greedy algorithms are easy to understand and implement because they follow a straightforward approach of making the best choice at each step.

  • Efficiency: They often have lower time complexity compared to other algorithms like dynamic programming, making them faster for certain problems.

  • Locally Optimal Decisions: By making locally optimal choices, greedy algorithms can quickly arrive at a solution without the need for complex backtracking.

  • Works Well for Certain Problems: Greedy algorithms are particularly effective for problems that exhibit the greedy choice property and optimal substructure, such as Minimum Spanning Tree and Huffman Coding.

Disadvantages of Greedy Algorithms

  • May Not Always Produce Optimal Solutions: Greedy algorithms focus on immediate benefits, which can sometimes lead to suboptimal solutions for problems where a global perspective is needed.

  • Limited Applicability: Greedy algorithms only work well for problems that satisfy the greedy choice property and optimal substructure; they may fail or give incorrect results otherwise.

  • No Backtracking: Once a choice is made, it cannot be undone, which can lead to incorrect results if the wrong choice is made early on.

  • Lack of Flexibility: Greedy algorithms are rigid in their approach, and modifying them to account for different problem constraints can be challenging.

A greedy algorithm is guaranteed to find the optimal solution when the problem has the greedy choice property and optimal substructure. Examples include Prim’s Algorithm for Minimum Spanning Tree and Dijkstra’s Algorithm for the shortest path.

No, greedy algorithms do not always find the best solution. They work well for certain problems but can fail to provide an optimal solution if the problem doesn’t have the greedy choice property.

A pure greedy algorithm makes a complete decision at each step, while a fractional greedy algorithm can make partial decisions, allowing parts of items to be selected, as seen in the Fractional Knapsack Problem.

A greedy algorithm might fail if the problem requires future considerations or if making the best local choice doesn’t lead to a globally optimal solution. For instance, in the 0/1 Knapsack Problem, a greedy approach can lead to suboptimal results.

The greedy choice property is the principle that making the locally optimal choice at each step will lead to a globally optimal solution. This property is essential for the success of a greedy algorithm.

Yes, greedy algorithms can be combined with other approaches, such as dynamic programming or backtracking, to improve performance or handle more complex problems.

Updated - 11 Feb 20255 mins readPublished : 18 Sep 2024

Recursive Algorithm: Examples, Complexity, Types, Uses

BFS (Breadth-First Search) Algorithm

0%