Bird
Raised Fist0
DSA Pythonprogramming~5 mins

Greedy vs DP How to Know Which to Apply in DSA Python - Complexity Comparison

Choose your learning style10 modes available
Time Complexity: Greedy vs DP How to Know Which to Apply
O(n log n) for Greedy, O(n * W) for DP
Understanding Time Complexity

We want to understand how to decide between greedy and dynamic programming (DP) approaches by looking at their time costs.

Which method runs faster and when should we use each?

Scenario Under Consideration

Analyze the time complexity of these two approaches solving the same problem.


# Greedy approach example
items = sorted(items, key=lambda x: x.value / x.weight, reverse=True)
result = 0
for item in items:
    if capacity >= item.weight:
        capacity -= item.weight
        result += item.value

# Dynamic Programming approach example
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    for w in range(capacity + 1):
        if items[i-1].weight <= w:
            dp[i][w] = max(dp[i-1][w], dp[i-1][w - items[i-1].weight] + items[i-1].value)
        else:
            dp[i][w] = dp[i-1][w]
    

The greedy code picks items by best value per weight quickly. The DP code tries all combinations to find the best total value.

Identify Repeating Operations

Look at the loops and repeated steps in each approach.

  • Greedy primary operation: Sorting items once, then one loop over all items.
  • Greedy loop count: Runs once over n items after sorting.
  • DP primary operation: Nested loops over items and capacity values.
  • DP loop count: Runs n times for items and capacity times for weight, so n * capacity.
How Execution Grows With Input

As input size grows, how do the operations increase?

Input Size (n)Capacity (W)Greedy OpsDP Ops
1050~10 + sorting10 * 50 = 500
1001000~100 + sorting100 * 1000 = 100,000
100010,000~1000 + sorting1000 * 10,000 = 10,000,000

Greedy grows mostly with number of items and sorting cost. DP grows with both items and capacity, multiplying operations.

Final Time Complexity

Time Complexity: O(n log n) for Greedy, O(n * W) for DP

Greedy is faster but less thorough; DP checks all possibilities and takes longer.

Common Mistake

[X] Wrong: "Greedy always gives the best answer quickly."

[OK] Correct: Greedy works only when local choices lead to global best. Otherwise, DP is needed to explore all options.

Interview Connect

Knowing when to pick greedy or DP shows you understand problem patterns and efficiency, a key skill in coding interviews.

Self-Check

"What if the capacity W is very large but the number of items n is small? How does that affect the time complexity choice between greedy and DP?"

Practice

(1/5)
1. Which of the following best describes when to use a greedy algorithm instead of dynamic programming?
easy
A. When the problem has optimal substructure and no overlapping subproblems
B. When the problem has overlapping subproblems and requires memoization
C. When the problem requires checking all possible combinations
D. When the problem involves sorting large datasets

Solution

  1. Step 1: Understand greedy algorithm conditions

    Greedy algorithms work when choosing the best option at each step leads to a global optimum, which means the problem has optimal substructure and no overlapping subproblems.
  2. Step 2: Compare with dynamic programming conditions

    Dynamic programming is used when problems have overlapping subproblems and require storing intermediate results (memoization) to avoid repeated work.
  3. Final Answer:

    When the problem has optimal substructure and no overlapping subproblems -> Option A
  4. Quick Check:

    Greedy = optimal substructure + no overlap [OK]
Hint: Use greedy if no overlapping subproblems exist [OK]
Common Mistakes:
  • Confusing overlapping subproblems as a greedy condition
  • Thinking greedy always finds the best solution
  • Using dynamic programming when greedy suffices
2. Which of the following Python code snippets correctly initializes a memoization dictionary for dynamic programming?
easy
A. memo = []
B. memo = {}
C. memo = set()
D. memo = 0

Solution

  1. Step 1: Identify the correct data structure for memoization

    Memoization requires storing key-value pairs of subproblem results, so a dictionary (hash map) is appropriate.
  2. Step 2: Check the options

    memo = {} initializes an empty dictionary, which is correct. Lists or sets do not store key-value pairs, and an integer cannot store multiple results.
  3. Final Answer:

    memo = {} -> Option B
  4. Quick Check:

    Memoization uses dictionary = {} [OK]
Hint: Use {} to store subproblem results in DP [OK]
Common Mistakes:
  • Using list or set instead of dictionary for memo
  • Initializing memo as a number
  • Confusing data structures for memoization
3. What is the output of the following Python code that uses a greedy approach to select intervals?
intervals = [(1, 3), (2, 5), (4, 7)]
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)
medium
A. [(1, 3), (2, 5)]
B. [(2, 5), (4, 7)]
C. [(1, 3), (4, 7)]
D. [(1, 3), (2, 5), (4, 7)]

Solution

  1. Step 1: Sort intervals by finish time

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

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

    [(1, 3), (4, 7)] -> Option C
  4. Quick Check:

    Greedy interval selection = [(1, 3), (4, 7)] [OK]
Hint: Sort by finish time, pick earliest finishing intervals [OK]
Common Mistakes:
  • Not sorting intervals by finish time
  • Selecting overlapping intervals
  • Appending intervals without condition
4. The following code attempts to solve the Fibonacci sequence using dynamic programming but has a bug. What is the error?
def fib(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 1:
        return n
    memo[n] = fib(n-1) + fib(n-2)
    return memo[n]

print(fib(5))
medium
A. Mutable default argument causes incorrect memoization across calls
B. Missing base case for n=0
C. Incorrect recursive calls fib(n-1) and fib(n-2)
D. Memo dictionary is not updated

Solution

  1. Step 1: Identify the use of mutable default argument

    The function uses memo={} as a default argument, which is mutable and shared across calls, causing unexpected behavior if fib is called multiple times.
  2. Step 2: Explain why this is a bug

    This can cause memo to retain values from previous calls, leading to incorrect results or memory issues.
  3. Final Answer:

    Mutable default argument causes incorrect memoization across calls -> Option A
  4. Quick Check:

    Mutable default dict in function = bug [OK]
Hint: Avoid mutable defaults like dict in function args [OK]
Common Mistakes:
  • Ignoring mutable default argument issue
  • Thinking base cases are missing
  • Assuming memo is not updated
5. You want to find the minimum number of coins to make a target amount using coin denominations [1, 3, 4]. Which approach is best and why? A greedy approach picks the largest coin first. Dynamic programming tries all combinations. Which is correct?
hard
A. Neither approach works for coin change problems
B. Greedy always works because picking largest coin reduces count
C. Greedy and dynamic programming give the same result here
D. Dynamic programming is needed because greedy fails for some amounts

Solution

  1. Step 1: Understand greedy approach limitation

    Greedy picks largest coin first, but for amount 6, greedy picks 4+1+1=3 coins, but optimal is 3+3=2 coins.
  2. Step 2: Recognize dynamic programming advantage

    Dynamic programming tries all combinations and finds minimum coins, handling cases where greedy fails.
  3. Final Answer:

    Dynamic programming is needed because greedy fails for some amounts -> Option D
  4. Quick Check:

    Coin change needs DP, greedy can fail [OK]
Hint: Use DP for coin change; greedy can fail [OK]
Common Mistakes:
  • Assuming greedy always finds minimum coins
  • Ignoring counterexamples where greedy fails
  • Thinking coin change is always greedy
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