Greedy 1
Greedy 1
Greedy-1
What is Greedy Algorithm?
Greedy is an algorithmic paradigm that builds up a solution piece by piece, always choosing the next piece
that offers the most obvious and immediate benefit.
A greedy algorithm is a problem-solving approach that involves making the best possible choice at each step,
hoping to achieve the overall best solution.
It focuses on the local optimal choice without considering the future consequences.
This algorithm is helpful when a problem can be broken down into smaller parts, and the solution to each part
contributes to solving the entire problem. It is commonly used to solve optimization problems where you need
to find the best solution from a range of possibilities.
Greedy Choice Property: The Greedy choice property states that a globally optimal solution can be achieved
by consistently making locally optimal choices. In other words, a Greedy algorithm selects the best option at
each step, considering only the current information and not the future consequences. It iteratively makes these
Greedy choices, reducing the original problem into smaller subproblems.
Optimal Substructure: Optimal substructure refers to a property of a problem where finding an optimal
solution to the problem involves finding optimal solutions to its subproblems. This means that the overall
optimal solution can be constructed by combining the optimal solutions of the smaller subproblems. By solving
these subproblems and building up their solutions, we can solve larger and more complex problems.
A basic structure:
Declare an empty result = 0
We make a greedy choice to select, If the choice is feasible add it to the final result
Return the result.
Ordered List of Resources: The problem should involve a set of resources, such as profits, costs, or values,
that can be arranged in a specific order
Maximum Resource Selection: The Greedy algorithm selects the maximum value or resource from the given
By considering these characteristics, the Greedy algorithm can make locally optimal choices at each step,
ultimately leading to an overall optimal or satisfactory solution.
These characteristic components help define and guide the behavior of a Greedy algorithm, enabling it to find
efficient and effective solutions for optimization problems.
The local decisions (or choices) must possess three characteristics as mentioned below:
Feasibility: The selected choice must fulfill the constraints
Optimality: The selected choice must be the best at that stage (locally optimal choice)
Irrevocability: The selected choice cannot be changed once it is made.
Immediate Feasible Solutions: The Greedy approach allows for quickly obtaining feasible solutions. It
focuses on making locally optimal choices at each step, without considering the overall consequences. This
can be advantageous in situations where obtaining a feasible solution immediately is more important than
finding the globally optimal solution
Recursive Division: The Greedy approach can simplify problem-solving by dividing the problem recursively
based on a condition, without the need to combine all the solutions. This can be seen in the activity
selection problem, where activities are selected based on certain criteria, allowing for efficient scheduling
without exhaustive combination calculations.
Scheduling and Resource Allocation: The greedy algorithm is effective in efficiently scheduling tasks or
allocating resources
Minimum Spanning Trees: It can be used to find the minimum spanning tree in a graph, connecting all
vertices with the minimum total edge weight
Coin Change Problem: The greedy algorithm solves the problem of making a change with the fewest coins
by selecting the highest-value coin that fits the remaining amount
Huffman Coding: It generates a prefix-free code for data compression by constructing a binary tree based
on character frequencies.
It is worth noting that not all optimization problems can be solved using the greedy algorithm, and there may
be cases where it produces suboptimal solutions. However, for many problems, it offers a quick and efficient
approximation of the optimal solution.
Coding Questions
Q1 Fractional Knapsack
Given the weights and profits of N items, in the form of {profit, weight} put these items in a knapsack of
capacity W to get the maximum total profit in the knapsack. In Fractional Knapsack, we can break items for
maximizing the total value of the knapsack.
Output: 240
Approach:
The algorithm used in the provided code is known as the Fractional Knapsack algorithm. It is a greedy
algorithm that selects items based on their profit-to-weight ratios, choosing the items with the highest ratios
The Fractional Knapsack algorithm works in cases where fractions of items can be included in the knapsack to
maximize the total profit. However, it does not guarantee an optimal solution in terms of selecting whole items
only (i.e., without fractional parts).
Output:
Time complexity: O(n log n), where n is the number of items. This is because the algorithm involves sorting the
items based on their profit-to-weight ratios.
Space complexity: O(1) because it uses a constant amount of additional space for variables and temporary
storage, regardless of the input size. The space required does not grow with the number of items, making it a
space-efficient algorithm.
There is one meeting room in a firm. There are N meetings in the form of (S[i], F[i]) where S[i] is the start time of
meeting i and F[i] is the finish time of meeting i. The task is to find the maximum number of meetings that can
be accommodated in the meeting room. Print all meeting numbers.
Constraints:
Input:
S[] = {1, 3, 0, 5, 8, 5}
Output:
1 2 4 5
Approach:
The idea is to solve the problem using the greedy approach i.e. sort the meetings by their finish time and then
start selecting meetings, starting with the one with least end time and then selecting other meetings such that
the start time of the current meeting is greater than the end time of last meeting selected.
Steps involved
Sort all pairs(Meetings) in increasing order of each pair’s second number(Finish time)
Select the first meeting of the sorted pair as the first Meeting in the room and push it into the result vector
and set a variable time_limit(say) with the second value(Finishing time) of the first selected meeting
Iterate from the second pair to the last pair of the array and if the value of the first element(Starting time of
meeting) of the current pair is greater than the previously selected pair’s finish time (time_limit) then select
the current pair and update the result vector (push selected meeting number into result vector) and
variable time_limit
Print the order of meeting from the result vector.
Output:
their finish times, which has the time complexity of O(nlogn). After sorting, we iterate over the sorted meetings
once to find the maximum number of meetings that can be accommodated, which takes O(n) time. So, overall
Space complexity: O(n) since we need to store the meetings in a list, and the size of the list is proportional to
Given N activities with their start and finish day given in arrays start[ ] and end[ ] respectively. Select the
maximum number of activities that can be performed by a single person, assuming that a person can only
Note: Duration of the activity includes both starting and ending day.
Input:
N = 4
start[] = {1, 3, 2, 5}
end[] = {2, 4, 3, 6}
Output:
Explanation:
Approach:
The greedy choice is to always pick the next activity whose finish time is least among the remaining activities
and the start time is more than or equal to the finish time of the previously selected activity. We can sort the
activities according to their finishing time so that we always consider the next activity as minimum finishing
time activity
Select the first activity from the sorted array and print it.
For the remaining activities in the sorted array, if the start time of this activity is greater than or equal to the
finish time of the previously selected activity then select this activity and print it.
Output:
Space complexity: O(n) since it uses an array of Activity objects to store the activities. The size of the array is
directly proportional to the number of activities, so the space complexity grows linearly with the input size.
You are a person in an island. There is only one shop in this island, this shop is open on all days of the week
except for Sunday. Consider following constraints:
Currently, it’s Monday, and you need to survive for the next S days.
Find the minimum number of days on which you need to buy food from the shop so that you can survive the
next S days, or determine that it isn’t possible to survive.
Input:
S = 10 N = 16 M = 2
Output:
Yes
Explanation: One possible solution is to buy a box on the first day (Monday), it’s sufficient to eat from this box up
to 8th day (Monday) inclusive. Now, on the 9th day (Tuesday), you buy another box and use the food in it to
survive the 9th and 10th day.
Input: 10 20 30
Output: No
Explanation: You can’t survive even if you buy food because the maximum number of units you can buy in one
day is less than the required food for one day.
Approach:
In this problem, the greedy approach of buying the food for some consecutive early days is the right direction.
If we can survive for the first 7 days then we can survive any number of days for that we need to check two
things
Check whether we can survive one day or not.
(S >= 7) If we buy food in the first 6 days of the week and we can survive for the week i.e. total food we can
buy in a week (6*N) is greater than or equal to total food we require to survive in a week (7*M) then we can
survive.
Output:
Time complexity: O(1) because it performs a fixed number of operations regardless of the input size.
Space complexity: O(1) as it only uses a constant amount of additional space to store the input variables and
local variables, regardless of the input size.