Bird
Raised Fist0
DSA Pythonprogramming~5 mins

Why Greedy Works and When It Fails in DSA Python - Performance Analysis

Choose your learning style10 modes available
Time Complexity: Why Greedy Works and When It Fails
O(n)
Understanding Time Complexity

We want to understand how fast greedy algorithms run and why they sometimes give the best answer quickly.

What makes greedy choices efficient or not for a problem?

Scenario Under Consideration

Analyze the time complexity of this simple greedy approach for coin change.


coins = [25, 10, 5, 1]
amount = 63
count = 0
for coin in coins:
    count += amount // coin
    amount %= coin
print(count)
    

This code picks the largest coin possible repeatedly to make change.

Identify Repeating Operations

Look for loops or repeated steps.

  • Primary operation: Loop over the list of coins once.
  • How many times: Exactly once per coin type (4 times here).
How Execution Grows With Input

The loop runs once for each coin type, no matter the amount.

Input Size (number of coin types)Approx. Operations
44
1010
100100

Pattern observation: Operations grow linearly with the number of coin types, not the amount.

Final Time Complexity

Time Complexity: O(n)

This means the time grows in a straight line with the number of coin types.

Common Mistake

[X] Wrong: "Greedy always finds the best answer quickly for any problem."

[OK] Correct: Greedy works only when local best choices lead to a global best. Some problems need more checks.

Interview Connect

Understanding when greedy works helps you pick the right tool fast and explain your choices clearly in interviews.

Self-Check

"What if the coin denominations were not sorted or standard? How would that affect the greedy approach's time complexity and correctness?"

Practice

(1/5)
1. What is the main reason a greedy algorithm works correctly for some problems?
easy
A. Because it sorts the input data before processing
B. Because it tries all possible solutions exhaustively
C. Because it uses recursion to explore all paths
D. Because making the best local choice leads to a globally optimal solution

Solution

  1. Step 1: Understand greedy algorithm principle

    A greedy algorithm makes the best choice at each step without reconsidering previous choices.
  2. Step 2: Connect local choices to global optimum

    For some problems, these local best choices add up to the best overall solution.
  3. Final Answer:

    Because making the best local choice leads to a globally optimal solution -> Option D
  4. Quick Check:

    Greedy = best local choice leads to global optimum [OK]
Hint: Greedy picks best now, works if global best follows [OK]
Common Mistakes:
  • Thinking greedy tries all solutions
  • Confusing greedy with recursion
  • Assuming sorting always means greedy
2. Which of the following is the correct syntax to pick the next item greedily from a sorted list items in Python?
easy
A. next_item = items.pop(0)
B. next_item = items[0]
C. next_item = items.pop()
D. next_item = items.remove(0)

Solution

  1. Step 1: Understand list methods for greedy selection

    To pick and remove the first item, pop(0) removes and returns it.
  2. Step 2: Check other options

    items[0] only accesses without removing; pop() removes last; remove(0) removes first occurrence of value 0, not index.
  3. Final Answer:

    next_item = items.pop(0) -> Option A
  4. Quick Check:

    pop(0) removes first item [OK]
Hint: pop(0) removes and returns first item [OK]
Common Mistakes:
  • Using items[0] without removing
  • Using pop() removes last item
  • Confusing remove() with pop()
3. Consider the following code that tries to select intervals greedily by earliest finish time:
intervals = [(1,4), (2,3), (3,5), (7,8)]
intervals.sort(key=lambda x: x[1])
selected = []
end = 0
for start, finish in intervals:
    if start >= end:
        selected.append((start, finish))
        end = finish
print(selected)
What is the output?
medium
A. [(2, 3), (7, 8)]
B. [(1, 4), (7, 8)]
C. [(2, 3), (3, 5), (7, 8)]
D. [(1, 4), (3, 5), (7, 8)]

Solution

  1. Step 1: Sort intervals by finish time

    Sorted intervals: (2,3), (1,4), (3,5), (7,8)
  2. Step 2: Select intervals greedily

    Start with end=0. (2,3) start=2 >=0, select it, end=3. Next (1,4) start=1<3 skip. Next (3,5) start=3>=3 select, end=5. Next (7,8) start=7>=5 select, end=8.
  3. Step 3: Final selected intervals

    [(2,3), (3,5), (7,8)]
  4. Final Answer:

    [(2, 3), (3, 5), (7, 8)] -> Option C
  5. Quick Check:

    Greedy interval selection by finish time = [(2,3),(3,5),(7,8)] [OK]
Hint: Sort by finish time, pick intervals starting after last end [OK]
Common Mistakes:
  • Not sorting by finish time
  • Selecting overlapping intervals
  • Updating end incorrectly
4. The following code tries to solve the coin change problem greedily but has a bug:
coins = [25, 10, 5, 1]
amount = 30
result = []
for coin in coins:
    while amount >= coin:
        result.append(coin)
        amount -= coin
print(result)
What is the bug in this greedy approach?
medium
A. It does not sort coins before using them
B. It fails for some coin sets where greedy is not optimal
C. It uses while instead of if
D. It does not handle zero amount correctly

Solution

  1. Step 1: Understand greedy coin change approach

    The code picks largest coin repeatedly until amount is zero.
  2. Step 2: Identify when greedy fails

    Greedy works for US coins but fails for some sets (e.g., coins=[10,6,1], amount=12 greedy picks 10+1+1=3 coins but optimal is 6+6=2 coins).
  3. Final Answer:

    It fails for some coin sets where greedy is not optimal -> Option B
  4. Quick Check:

    Greedy coin change fails on some coin sets [OK]
Hint: Greedy coin change fails if coin set is non-canonical [OK]
Common Mistakes:
  • Assuming greedy always gives minimum coins
  • Thinking sorting is missing
  • Confusing while and if usage
5. You want to select the minimum number of intervals to cover a timeline from 0 to 10. Intervals are: [(0,3), (2,6), (5,10), (7,10), (1,4)]. Which greedy strategy will fail to find the minimum set and why? Options: A) Always pick the interval with earliest start time B) Always pick the interval with shortest length C) Always pick the interval with earliest finish time D) Always pick the interval covering the largest uncovered part Choose the failing strategy and explain why.
hard
A. Always picking shortest length fails because it may need many intervals to cover timeline
B. Always picking earliest start fails because it may pick small intervals leaving gaps
C. Always picking earliest finish time works correctly here
D. Always picking largest uncovered part always finds minimum intervals

Solution

  1. Step 1: Analyze shortest length strategy

    Picking shortest intervals first may cover small parts, requiring many intervals to cover entire timeline.
  2. Step 2: Compare with other strategies

    Earliest finish time is classic greedy that works for interval covering. Largest uncovered part is a complex greedy that can work. Earliest start can fail but less obviously here.
  3. Final Answer:

    Always picking shortest length fails because it may need many intervals to cover timeline -> Option A
  4. Quick Check:

    Shortest length greedy fails for minimum interval cover [OK]
Hint: Shortest intervals first often leads to many intervals needed [OK]
Common Mistakes:
  • Assuming earliest start always works
  • Thinking largest uncovered part is always greedy
  • Confusing shortest length with earliest finish
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard