PapersAdda

Greedy Algorithm Questions Placement

18 min read
Uncategorized
Advertisement Placement

Greedy Algorithm Questions for Placement 2026 (with Solutions)

Last Updated: March 2026


Overview

Greedy algorithms make locally optimal choices at each step with the hope of finding a global optimum. While not always optimal, greedy algorithms provide efficient solutions for many problems and are frequently tested in technical interviews. Understanding when to apply greedy vs dynamic programming is crucial.

Companies Focused on Greedy Algorithms

  • Google: Interval scheduling, Huffman coding, meeting rooms
  • Amazon: Activity selection, jump game, task scheduling
  • Microsoft: Fractional knapsack, gas station, candy distribution
  • Meta: Reconstruct queue, remove k digits
  • Apple: Job sequencing, minimum platforms
  • Uber: Route optimization with greedy heuristics

Core Concepts

Greedy Algorithm Properties

A problem can be solved using greedy approach if it has:

  1. Greedy Choice Property: A global optimum can be reached by choosing local optimum at each step
  2. Optimal Substructure: An optimal solution contains optimal solutions to subproblems

Common Greedy Strategies

1. Sorting-based Greedy
   - Sort by finish time (activity selection)
   - Sort by value/weight ratio (fractional knapsack)
   - Sort by deadline (job sequencing)

2. Selection-based Greedy
   - Always pick the best available option
   - Discard options that don't satisfy constraints

3. Exchange Argument
   - Prove greedy choice doesn't worsen optimal solution
   - Show we can exchange elements to get greedy solution

Greedy vs Dynamic Programming

AspectGreedyDynamic Programming
DecisionOne shot, never reconsiderMultiple choices, may reconsider
OptimalNot always optimalAlways optimal
SpeedFasterSlower
ExamplesDijkstra, KruskalFloyd-Warshall, 0/1 Knapsack

20 Frequently Asked Coding Questions


Question 1: Activity Selection Problem

Problem: Select maximum number of activities that don't overlap.

class Solution:
    def activitySelection(self, start, end):
        """
        start: list of start times
        end: list of end times
        """
        n = len(start)
        
        # Create activities and sort by end time
        activities = [(start[i], end[i]) for i in range(n)]
        activities.sort(key=lambda x: x[1])  # Sort by end time
        
        selected = [activities[0]]
        last_end = activities[0][1]
        
        for i in range(1, n):
            if activities[i][0] >= last_end:
                selected.append(activities[i])
                last_end = activities[i][1]
        
        return selected
    
    # Count only
    def maxActivities(self, start, end):
        activities = sorted(zip(start, end), key=lambda x: x[1])
        count = 1
        last_end = activities[0][1]
        
        for i in range(1, len(activities)):
            if activities[i][0] >= last_end:
                count += 1
                last_end = activities[i][1]
        
        return count

# Driver Code
start = [1, 3, 0, 5, 8, 5]
end = [2, 4, 6, 7, 9, 9]
sol = Solution()
print(sol.maxActivities(start, end))  # Output: 4
print(sol.activitySelection(start, end))
# Output: [(1, 2), (3, 4), (5, 7), (8, 9)]

Time Complexity: O(n log n) for sorting
Space Complexity: O(n)


Question 2: Fractional Knapsack

Problem: Maximize value in knapsack with fractional items allowed.

class Solution:
    def fractionalKnapsack(self, values, weights, capacity):
        """
        values: list of item values
        weights: list of item weights
        capacity: knapsack capacity
        """
        n = len(values)
        
        # Calculate value/weight ratio for each item
        items = [(values[i] / weights[i], values[i], weights[i]) 
                 for i in range(n)]
        
        # Sort by ratio in descending order
        items.sort(reverse=True, key=lambda x: x[0])
        
        total_value = 0.0
        remaining_capacity = capacity
        
        for ratio, value, weight in items:
            if remaining_capacity >= weight:
                # Take whole item
                total_value += value
                remaining_capacity -= weight
            else:
                # Take fraction of item
                fraction = remaining_capacity / weight
                total_value += value * fraction
                break  # Knapsack is full
        
        return total_value

# Driver Code
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
sol = Solution()
print(sol.fractionalKnapsack(values, weights, capacity))  # Output: 240.0

Time Complexity: O(n log n)
Space Complexity: O(n)


Question 3: N Meetings in One Room

Problem: Find maximum meetings that can be held in one room.

class Solution:
    def maxMeetings(self, start, end):
        n = len(start)
        
        # Create meeting objects with original indices
        meetings = [(start[i], end[i], i + 1) for i in range(n)]
        
        # Sort by end time
        meetings.sort(key=lambda x: x[1])
        
        selected = [meetings[0][2]]  # Store meeting numbers
        last_end = meetings[0][1]
        
        for i in range(1, n):
            if meetings[i][0] > last_end:
                selected.append(meetings[i][2])
                last_end = meetings[i][1]
        
        return selected

# Driver Code
start = [1, 3, 0, 5, 8, 5]
end = [2, 4, 6, 7, 9, 9]
sol = Solution()
print(sol.maxMeetings(start, end))  # Output: [1, 2, 4, 5]

Time Complexity: O(n log n)
Space Complexity: O(n)


Question 4: Job Sequencing with Deadlines

Problem: Schedule jobs to maximize profit, each job takes unit time.

class Solution:
    def jobSequencing(self, jobs):
        """
        jobs: list of (job_id, deadline, profit)
        """
        # Sort by profit in descending order
        jobs.sort(key=lambda x: x[2], reverse=True)
        
        # Find maximum deadline
        max_deadline = max(job[1] for job in jobs)
        
        # Result array: slot -> job_id
        result = [-1] * (max_deadline + 1)
        total_profit = 0
        job_count = 0
        
        for job_id, deadline, profit in jobs:
            # Find available slot from deadline backwards
            for slot in range(min(deadline, max_deadline), 0, -1):
                if result[slot] == -1:
                    result[slot] = job_id
                    total_profit += profit
                    job_count += 1
                    break
        
        return job_count, total_profit, [x for x in result if x != -1]

# Optimized version using Union-Find
class JobSequencingOptimized:
    def __init__(self, n):
        self.parent = list(range(n + 1))
    
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    
    def jobSequencing(self, jobs):
        jobs.sort(key=lambda x: x[2], reverse=True)
        max_deadline = max(job[1] for job in jobs)
        
        uf = JobSequencingOptimized(max_deadline)
        total_profit = 0
        job_count = 0
        
        for job_id, deadline, profit in jobs:
            available_slot = uf.find(deadline)
            if available_slot > 0:
                total_profit += profit
                job_count += 1
                uf.parent[available_slot] = uf.find(available_slot - 1)
        
        return job_count, total_profit

# Driver Code
jobs = [('a', 4, 20), ('b', 1, 10), ('c', 1, 40), 
        ('d', 1, 30)]
sol = Solution()
print(sol.jobSequencing(jobs))  # Output: (2, 60, ['c', 'a'])

Time Complexity: O(n²) or O(n log n) with Union-Find
Space Complexity: O(max_deadline)


Question 5: Minimum Number of Coins

Problem: Find minimum coins needed to make a given amount (Indian currency).

class Solution:
    def minCoins(self, coins, amount):
        """
        coins: available denominations (should include 1)
        amount: target amount
        """
        # Sort in descending order
        coins.sort(reverse=True)
        
        coin_count = 0
        remaining = amount
        used_coins = []
        
        for coin in coins:
            if remaining >= coin:
                count = remaining // coin
                coin_count += count
                remaining -= coin * count
                used_coins.extend([coin] * count)
            
            if remaining == 0:
                break
        
        return coin_count, used_coins

# Driver Code
coins = [1, 2, 5, 10, 20, 50, 100, 500, 1000]
amount = 93
sol = Solution()
print(sol.minCoins(coins, amount))  # Output: (5, [50, 20, 20, 2, 1])

Time Complexity: O(n log n) for sorting, O(amount) in worst case
Space Complexity: O(1)


Question 6: Huffman Coding

Problem: Generate optimal prefix codes for characters based on frequency.

import heapq
from collections import defaultdict

class HuffmanNode:
    def __init__(self, char, freq):
        self.char = char
        self.freq = freq
        self.left = None
        self.right = None
    
    def __lt__(self, other):
        return self.freq < other.freq

class Solution:
    def huffmanCoding(self, chars, freqs):
        """
        chars: list of characters
        freqs: list of frequencies
        """
        # Create min heap
        min_heap = [HuffmanNode(chars[i], freqs[i]) for i in range(len(chars))]
        heapq.heapify(min_heap)
        
        # Build Huffman tree
        while len(min_heap) > 1:
            left = heapq.heappop(min_heap)
            right = heapq.heappop(min_heap)
            
            # Create internal node
            merged = HuffmanNode(None, left.freq + right.freq)
            merged.left = left
            merged.right = right
            
            heapq.heappush(min_heap, merged)
        
        # Generate codes
        root = min_heap[0]
        codes = {}
        self._generateCodes(root, "", codes)
        
        return codes
    
    def _generateCodes(self, node, current_code, codes):
        if node is None:
            return
        
        if node.char is not None:
            codes[node.char] = current_code or "0"
            return
        
        self._generateCodes(node.left, current_code + "0", codes)
        self._generateCodes(node.right, current_code + "1", codes)

# Driver Code
chars = ['a', 'b', 'c', 'd', 'e', 'f']
freqs = [5, 9, 12, 13, 16, 45]
sol = Solution()
codes = sol.huffmanCoding(chars, freqs)
print(codes)
# Output: {'f': '0', 'c': '100', 'd': '101', 'a': '1100', 'b': '1101', 'e': '111'}

Time Complexity: O(n log n)
Space Complexity: O(n)


Question 7: Minimum Platforms Required

Problem: Find minimum number of platforms needed for trains.

class Solution:
    def findPlatform(self, arr, dep):
        """
        arr: arrival times
        dep: departure times
        """
        # Sort both arrays
        arr.sort()
        dep.sort()
        
        n = len(arr)
        platforms_needed = 0
        max_platforms = 0
        
        i = j = 0
        
        while i < n and j < n:
            if arr[i] <= dep[j]:
                # Train arrives, need platform
                platforms_needed += 1
                max_platforms = max(max_platforms, platforms_needed)
                i += 1
            else:
                # Train departs, free platform
                platforms_needed -= 1
                j += 1
        
        return max_platforms

# Driver Code
arr = [900, 940, 950, 1100, 1500, 1800]
dep = [910, 1200, 1120, 1130, 1900, 2000]
sol = Solution()
print(sol.findPlatform(arr, dep))  # Output: 3

Time Complexity: O(n log n)
Space Complexity: O(1)


Question 8: Jump Game

Problem: Determine if you can reach the last index.

class Solution:
    def canJump(self, nums):
        max_reach = 0
        n = len(nums)
        
        for i in range(n):
            if i > max_reach:
                return False
            
            max_reach = max(max_reach, i + nums[i])
            
            if max_reach >= n - 1:
                return True
        
        return True
    
    # Find minimum jumps
    def jump(self, nums):
        n = len(nums)
        if n <= 1:
            return 0
        
        jumps = 0
        current_end = 0
        farthest = 0
        
        for i in range(n - 1):
            farthest = max(farthest, i + nums[i])
            
            if i == current_end:
                jumps += 1
                current_end = farthest
                
                if current_end >= n - 1:
                    break
        
        return jumps

# Driver Code
nums = [2, 3, 1, 1, 4]
sol = Solution()
print(sol.canJump(nums))  # Output: True
print(sol.jump(nums))     # Output: 2

Time Complexity: O(n)
Space Complexity: O(1)


Question 9: Gas Station

Problem: Find starting gas station to complete circuit.

class Solution:
    def canCompleteCircuit(self, gas, cost):
        n = len(gas)
        total_gas = 0
        total_cost = 0
        current_tank = 0
        start_station = 0
        
        for i in range(n):
            total_gas += gas[i]
            total_cost += cost[i]
            current_tank += gas[i] - cost[i]
            
            # If tank is negative, can't start from current station
            if current_tank < 0:
                start_station = i + 1
                current_tank = 0
        
        return start_station if total_gas >= total_cost else -1

# Driver Code
gas = [1, 2, 3, 4, 5]
cost = [3, 4, 5, 1, 2]
sol = Solution()
print(sol.canCompleteCircuit(gas, cost))  # Output: 3

Time Complexity: O(n)
Space Complexity: O(1)


Question 10: Candy Distribution

Problem: Distribute candies so each child gets at least 1 and higher-rated children get more.

class Solution:
    def candy(self, ratings):
        n = len(ratings)
        candies = [1] * n
        
        # Left to right pass
        for i in range(1, n):
            if ratings[i] > ratings[i - 1]:
                candies[i] = candies[i - 1] + 1
        
        # Right to left pass
        for i in range(n - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                candies[i] = max(candies[i], candies[i + 1] + 1)
        
        return sum(candies)

# Driver Code
ratings = [1, 0, 2]
sol = Solution()
print(sol.candy(ratings))  # Output: 5

Time Complexity: O(n)
Space Complexity: O(n), can be optimized to O(1)


Question 11: Remove K Digits

Problem: Remove k digits to form the smallest possible number.

class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        stack = []
        
        for digit in num:
            # Remove larger digits from stack
            while k > 0 and stack and stack[-1] > digit:
                stack.pop()
                k -= 1
            stack.append(digit)
        
        # Remove remaining digits from end
        while k > 0:
            stack.pop()
            k -= 1
        
        # Remove leading zeros
        result = ''.join(stack).lstrip('0')
        
        return result if result else "0"

# Driver Code
num = "1432219"
k = 3
sol = Solution()
print(sol.removeKdigits(num, k))  # Output: "1219"

Time Complexity: O(n)
Space Complexity: O(n)


Question 12: Queue Reconstruction by Height

Problem: Reconstruct queue from (height, k) pairs.

class Solution:
    def reconstructQueue(self, people):
        """
        people: list of [height, k] where k is number of people in front
        who are taller or same height
        """
        # Sort by height descending, then k ascending
        people.sort(key=lambda x: (-x[0], x[1]))
        
        result = []
        for person in people:
            # Insert at position k
            result.insert(person[1], person)
        
        return result

# Driver Code
people = [[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]]
sol = Solution()
print(sol.reconstructQueue(people))
# Output: [[5, 0], [7, 0], [5, 2], [6, 1], [4, 4], [7, 1]]

Time Complexity: O(n²) due to insert, can be O(n log n) with advanced DS
Space Complexity: O(n)


Question 13: Assign Cookies

Problem: Maximize number of children satisfied with cookies.

class Solution:
    def findContentChildren(self, g, s):
        """
        g: greed factors of children
        s: sizes of cookies
        """
        g.sort()
        s.sort()
        
        child_i = cookie_j = 0
        content_children = 0
        
        while child_i < len(g) and cookie_j < len(s):
            if s[cookie_j] >= g[child_i]:
                # Cookie satisfies child
                content_children += 1
                child_i += 1
            cookie_j += 1
        
        return content_children

# Driver Code
g = [1, 2, 3]  # Greed factors
s = [1, 1]     # Cookie sizes
sol = Solution()
print(sol.findContentChildren(g, s))  # Output: 1

Time Complexity: O(n log n + m log m)
Space Complexity: O(1)


Question 14: Non-overlapping Intervals

Problem: Find minimum intervals to remove for no overlaps.

class Solution:
    def eraseOverlapIntervals(self, intervals):
        if not intervals:
            return 0
        
        # Sort by end time
        intervals.sort(key=lambda x: x[1])
        
        count = 0
        last_end = intervals[0][1]
        
        for i in range(1, len(intervals)):
            if intervals[i][0] < last_end:
                # Overlapping, remove this interval
                count += 1
            else:
                # Non-overlapping, keep this
                last_end = intervals[i][1]
        
        return count
    
    # Alternative: Find maximum non-overlapping
    def maxNonOverlapping(self, intervals):
        if not intervals:
            return 0
        
        intervals.sort(key=lambda x: x[1])
        
        count = 1
        last_end = intervals[0][1]
        
        for i in range(1, len(intervals)):
            if intervals[i][0] >= last_end:
                count += 1
                last_end = intervals[i][1]
        
        return count

# Driver Code
intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]
sol = Solution()
print(sol.eraseOverlapIntervals(intervals))  # Output: 1

Time Complexity: O(n log n)
Space Complexity: O(1)


Question 15: Boats to Save People

Problem: Minimum boats to carry people with weight limit.

class Solution:
    def numRescueBoats(self, people, limit):
        people.sort()
        
        left, right = 0, len(people) - 1
        boats = 0
        
        while left <= right:
            if people[left] + people[right] <= limit:
                # Both can fit
                left += 1
            # Heaviest always goes
            right -= 1
            boats += 1
        
        return boats

# Driver Code
people = [3, 2, 2, 1]
limit = 3
sol = Solution()
print(sol.numRescueBoats(people, limit))  # Output: 3

Time Complexity: O(n log n)
Space Complexity: O(1)


Question 16: Partition Labels

Problem: Partition string so each letter appears in at most one part.

class Solution:
    def partitionLabels(self, s: str):
        # Find last occurrence of each character
        last_occurrence = {char: i for i, char in enumerate(s)}
        
        partitions = []
        start = end = 0
        
        for i, char in enumerate(s):
            end = max(end, last_occurrence[char])
            
            if i == end:
                # Current partition ends here
                partitions.append(end - start + 1)
                start = i + 1
        
        return partitions

# Driver Code
s = "ababcbacadefegdehijhklij"
sol = Solution()
print(sol.partitionLabels(s))  # Output: [9, 7, 8]

Time Complexity: O(n)
Space Complexity: O(1) - Fixed 26 characters


Question 17: Hand of Straights

Problem: Check if hand can be grouped into straights of size W.

from collections import Counter

class Solution:
    def isNStraightHand(self, hand, W):
        if len(hand) % W != 0:
            return False
        
        count = Counter(hand)
        
        for card in sorted(count):
            if count[card] > 0:
                needed = count[card]
                # Try to form straights starting from this card
                for i in range(W):
                    if count[card + i] < needed:
                        return False
                    count[card + i] -= needed
        
        return True

# Driver Code
hand = [1, 2, 3, 6, 2, 3, 4, 7, 8]
W = 3
sol = Solution()
print(sol.isNStraightHand(hand, W))  # Output: True

Time Complexity: O(n log n)
Space Complexity: O(n)


Question 18: Minimum Cost to Hire K Workers

Problem: Hire exactly K workers minimizing cost (quality + wage ratio).

import heapq

class Solution:
    def mincostToHireWorkers(self, quality, wage, K):
        n = len(quality)
        
        # Calculate ratio for each worker
        workers = [(wage[i] / quality[i], quality[i]) for i in range(n)]
        
        # Sort by ratio
        workers.sort()
        
        # Max heap for qualities (using negative for max heap)
        max_heap = []
        sum_quality = 0
        min_cost = float('inf')
        
        for ratio, q in workers:
            heapq.heappush(max_heap, -q)
            sum_quality += q
            
            if len(max_heap) > K:
                sum_quality += heapq.heappop(max_heap)
            
            if len(max_heap) == K:
                min_cost = min(min_cost, sum_quality * ratio)
        
        return min_cost

# Driver Code
quality = [10, 20, 5]
wage = [70, 50, 30]
K = 2
sol = Solution()
print(sol.mincostToHireWorkers(quality, wage, K))  # Output: 105.0

Time Complexity: O(n log n)
Space Complexity: O(K)


Question 19: Two City Scheduling

Problem: Minimize cost to send exactly n people to each city.

class Solution:
    def twoCitySchedCost(self, costs):
        """
        costs: [[costA, costB], ...]
        """
        n = len(costs) // 2
        
        # Sort by difference (costA - costB)
        # Negative difference = cheaper to send to A
        # Positive difference = cheaper to send to B
        costs.sort(key=lambda x: x[0] - x[1])
        
        total_cost = 0
        
        # First n go to city A
        for i in range(n):
            total_cost += costs[i][0]
        
        # Last n go to city B
        for i in range(n, 2 * n):
            total_cost += costs[i][1]
        
        return total_cost

# Driver Code
costs = [[10, 20], [30, 200], [400, 50], [30, 20]]
sol = Solution()
print(sol.twoCitySchedCost(costs))  # Output: 110

Time Complexity: O(n log n)
Space Complexity: O(1)


Question 20: Create Maximum Number

Problem: Create maximum number of length k from two arrays.

class Solution:
    def maxNumber(self, nums1, nums2, k):
        def pick_max(nums, k):
            """Pick k digits to form maximum number"""
            drop = len(nums) - k
            stack = []
            for num in nums:
                while drop and stack and stack[-1] < num:
                    stack.pop()
                    drop -= 1
                stack.append(num)
            return stack[:k]
        
        def merge(a, b):
            """Merge two arrays to form maximum"""
            result = []
            while a or b:
                if a > b:
                    result.append(a.pop(0))
                else:
                    result.append(b.pop(0))
            return result
        
        max_result = [0] * k
        
        for i in range(max(0, k - len(nums2)), min(k, len(nums1)) + 1):
            part1 = pick_max(nums1, i)
            part2 = pick_max(nums2, k - i)
            merged = merge(part1[:], part2[:])
            max_result = max(max_result, merged)
        
        return max_result

# Driver Code
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
sol = Solution()
print(sol.maxNumber(nums1, nums2, k))  # Output: [9, 8, 6, 5, 3]

Time Complexity: O(k × (m + n))
Space Complexity: O(k)


MCQ Questions

Question 1

Which property must a problem have for greedy algorithm to work optimally?

  • A) Overlapping subproblems
  • B) Greedy choice property
  • C) Both A and B
  • D) None of the above

Question 2

What is the time complexity of activity selection problem?

  • A) O(n)
  • B) O(n log n)
  • C) O(n²)
  • D) O(2^n)

Question 3

Fractional knapsack uses which approach?

  • A) Dynamic Programming
  • B) Greedy
  • C) Backtracking
  • D) Divide and Conquer

Question 4

Why doesn't greedy work for 0/1 knapsack?

  • A) It requires sorting
  • B) Items cannot be divided
  • C) It's too slow
  • D) Memory constraints

Question 5

In Huffman coding, what type of tree is built?

  • A) Binary Search Tree
  • B) Full Binary Tree
  • C) Complete Binary Tree
  • D) Balanced Binary Tree

Interview Tips for Greedy Algorithms

  1. Identify greedy problems:

    • Optimization problems
    • Making locally optimal choices leads to global optimum
    • Problems involving sorting and selection
  2. Prove correctness:

    • Use exchange argument
    • Show greedy choice doesn't worsen solution
    • Prove optimal substructure
  3. Common greedy strategies:

    • Sort by some criteria (finish time, ratio, deadline)
    • Always pick the best available option
    • Two-pointer technique
  4. When greedy fails:

    • Try dynamic programming instead
    • Problems requiring future information
    • Problems with complex constraints
  5. Practice problems:

    • Interval scheduling variants
    • Resource allocation
    • String manipulation (remove k digits)
    • Array partitioning

Frequently Asked Questions

Q1: How do I know if a problem can be solved using greedy?

A: Check if making locally optimal choices leads to global optimum. Look for problems involving sorting, selection, or resource allocation. Try to prove using exchange argument.

Q2: What is the difference between greedy and dynamic programming?

A: Greedy makes one choice and never looks back. DP explores all choices and uses memoization. Greedy is faster but doesn't always give optimal solution.

Q3: Why does activity selection sort by finish time?

A: Sorting by finish time leaves maximum remaining time for other activities. This greedy choice allows accommodating maximum activities.

Q4: Can greedy be used for graph problems?

A: Yes! Dijkstra's shortest path, Prim's MST, and Kruskal's MST all use greedy approaches.

Q5: What is the exchange argument in greedy proofs?

A: Exchange argument shows that any optimal solution can be transformed into the greedy solution without worsening the result, proving greedy is also optimal.


Master these greedy problems to recognize patterns in interviews. Always try to prove why greedy works (or doesn't) for a given problem.

Advertisement Placement

Explore this topic cluster

More resources in Uncategorized

Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.

More in Uncategorized

More from PapersAdda

Share this article: