What are the 4 Greedy Algorithms?
When we talk about computer science and problem-solving, there are many different approaches an algorithm can take. One particularly useful and often intuitive strategy is called a "greedy algorithm." Think of it like making the best possible choice at each moment, hoping that these immediate best decisions will lead to an overall best solution. While this doesn't always guarantee the absolute perfect answer for every single problem, it's remarkably effective for a surprising number of common challenges. In essence, a greedy algorithm builds up a solution piece by piece, always selecting the most optimal option available at that particular step without considering the future consequences of that choice beyond the immediate gain. This makes them generally faster and simpler to implement than other more complex algorithmic approaches.
While there isn't a rigid, universally agreed-upon list of *exactly* four "named" greedy algorithms that encompass every single instance, we can identify four prominent and distinct categories or types of problems where the greedy strategy is most commonly and effectively applied. These are:
- Activity Selection Problem
- Huffman Coding
- Minimum Spanning Tree (MST) Algorithms (Prim's and Kruskal's)
- Coin Change Problem (with certain constraints)
Let's dive into each of these in detail.
1. Activity Selection Problem
This is a classic example that perfectly illustrates the greedy approach. Imagine you have a set of activities, each with a start time and a finish time, and you want to select the maximum number of non-overlapping activities that can be performed by a single person or machine. The greedy strategy here is beautifully simple:
- Sort the activities by their finish times in ascending order. This is the crucial first step.
- Select the first activity (the one that finishes earliest). This activity is guaranteed to be part of an optimal solution because it leaves the maximum amount of time available for subsequent activities.
- Iterate through the remaining activities. For each subsequent activity, if its start time is greater than or equal to the finish time of the previously selected activity, select it.
- Continue this process until all activities have been considered.
By always picking the activity that finishes soonest, you are maximizing the opportunity to fit in more activities later. This greedy choice at each step directly contributes to the overall goal of maximizing the total number of selected activities.
2. Huffman Coding
Huffman coding is a data compression technique. It's a prime example of a greedy algorithm used to assign variable-length codes to input characters, based on the frequencies of their occurrences. The goal is to minimize the total length of the encoded message. Here's how the greedy approach works:
- Create a leaf node for each character, with its frequency as its weight.
- Put all these leaf nodes into a min-priority queue. The priority is determined by the frequency.
- While there is more than one node in the queue:
- Extract the two nodes with the smallest frequencies.
- Create a new internal node whose children are these two extracted nodes. The weight of the new node is the sum of the weights of its children.
- Insert this new internal node back into the priority queue.
- The resulting tree is the Huffman tree. By assigning 0 to the left branches and 1 to the right branches (or vice-versa), you can derive the binary codes for each character.
The greedy choice here is to repeatedly combine the two least frequent characters (or groups of characters represented by internal nodes). This ensures that the most frequent characters get the shortest codes, and the least frequent characters get the longest codes, leading to optimal compression.
3. Minimum Spanning Tree (MST) Algorithms (Prim's and Kruskal's)
In graph theory, a Minimum Spanning Tree (MST) of a connected, undirected graph is a subgraph that connects all the vertices together, without any cycles, and with the minimum possible total edge weight. Both Prim's algorithm and Kruskal's algorithm are greedy algorithms that solve this problem, but they do so with slightly different approaches:
a) Prim's Algorithm
Prim's algorithm grows the MST from a single starting vertex. It's like building a connected structure outwards:
- Initialize the MST with a single vertex chosen arbitrarily.
- Repeatedly add the cheapest edge that connects a vertex in the current MST to a vertex not yet in the MST.
- Continue until all vertices are included in the MST.
The greedy choice is always to pick the cheapest edge that expands the current connected component of the MST without creating a cycle.
b) Kruskal's Algorithm
Kruskal's algorithm, on the other hand, builds the MST by considering edges from smallest weight to largest:
- Sort all the edges in the graph in non-decreasing order of their weights.
- Initialize the MST with no edges and all vertices as separate components.
- Iterate through the sorted edges. For each edge, if adding it to the MST does not form a cycle, add it.
- Stop when the MST contains V-1 edges, where V is the number of vertices.
The greedy choice here is to pick the smallest available edge that doesn't create a cycle. Both Prim's and Kruskal's algorithms, despite their different strategies, are guaranteed to find an MST because of the "cut property" of MSTs, which underpins the correctness of the greedy approach in this context.
4. Coin Change Problem (with certain constraints)
The coin change problem asks for the minimum number of coins needed to make a given amount of change, using a given set of coin denominations. The greedy approach works for this problem *only* if the coin system is "canonical," meaning it's the type of system we typically use (like US currency: pennies, nickels, dimes, quarters). For these canonical systems, the greedy strategy is:
- Start with the largest denomination coin that is less than or equal to the remaining amount needed.
- Take as many of that coin as possible without exceeding the remaining amount.
- Subtract the value of the coins taken from the remaining amount.
- Repeat with the next largest denomination coin until the remaining amount is zero.
For example, to make change for 78 cents with US currency:
- Take 3 quarters (75 cents). Remaining: 3 cents.
- Take 3 pennies (3 cents). Remaining: 0 cents.
Frequently Asked Questions (FAQ)
How do greedy algorithms differ from dynamic programming?
Greedy algorithms make locally optimal choices at each step, hoping to reach a globally optimal solution. They don't reconsider past choices. Dynamic programming, on the other hand, solves subproblems and stores their solutions to avoid recomputation. It explores all possible options for subproblems to guarantee a globally optimal solution, often by building up from smaller solutions to larger ones.
Why are greedy algorithms often preferred?
Greedy algorithms are often preferred because they are typically simpler to design, implement, and understand compared to more complex algorithms like dynamic programming. They are also generally more efficient in terms of time complexity, as they don't explore as many possibilities.
When might a greedy algorithm fail?
A greedy algorithm might fail to find the globally optimal solution if a locally optimal choice prevents a better overall solution later on. This is evident in the coin change problem with non-canonical coin systems, where picking the largest coin first doesn't always lead to the minimum number of coins.
Are there other examples of greedy algorithms?
Yes, there are many other examples. For instance, Dijkstra's algorithm for finding the shortest path in a graph (under certain conditions) and fractional knapsack problem are also solved using greedy strategies.

