When should you use a greedy algorithm rather than a dynamic program?
A greedy algorithm commits to one choice at each step and never revises it, usually picking the locally best option. It works when that local choice can never hurt the final answer, which is a property you have to prove rather than assume. A dynamic program keeps the best answer for every state and combines them, which is what you need when a locally attractive choice can rule out a better global outcome.
def max_profit(prices):
lowest = prices[0]
best = 0
for price in prices[1:]:
best = max(best, price - lowest)
lowest = min(lowest, price)
return best
print(max_profit([7, 1, 5, 3, 6, 4]))The output is 5, which is the profit from buying at one and selling at six.
The mechanism is that keeping the lowest price seen so far is always safe, because any future sale can use that lowest price no matter when it happens. There is no state that has to be remembered beyond that one value, so there is nothing for a dynamic program to combine.
The trade-off to name is the proof burden. Greedy is faster and uses less space, usually linear time and constant space, but you are betting on the problem's structure. When the exchange argument does not hold, greedy silently produces a wrong answer, and that is exactly what the interviewer is testing when they offer both variants of a problem. The other point is that a dynamic program is often the safer default, since it works whenever the local choice is safe and the cost is only a bigger table.