121. Best Time to Buy and Sell Stock(Java, Easy, O(n))


Problem Statement
You are given an array prices
where prices[i]
is the price of a given stock on the ith day.
You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.
Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0
.
Solution Approach
class Solution {
public int maxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
for (int price: prices) {
// buy low sell high
if (price < minPrice) {
minPrice = price;
}
else if ((price - minPrice) > maxProfit) {
// you won't want to update profit when price is lower
maxProfit = price - minPrice;
}
}
return maxProfit;
}
}
Algorithm Explanation
Core Strategy: One-Pass Tracking
The algorithm uses a single pass through the array to track two key values:
- Minimum price seen so far (
minPrice
) - potential buying point - Maximum profit possible (
maxProfit
) - best profit achievable
Step-by-Step Logic
Step 1: Initialize Variables
int minPrice = Integer.MAX_VALUE; // Track lowest price seen
int maxProfit = 0; // Track best profit so far
Step 2: Process Each Price
For each price in the array, we have two scenarios:
Scenario A: New Minimum Price Found
if (price < minPrice) {
minPrice = price; // Update potential buying point
}
- When we find a lower price, it becomes our new potential buying point
- All future selling opportunities will be calculated against this new minimum
Scenario B: Potential Selling Opportunity
else if ((price - minPrice) > maxProfit) {
maxProfit = price - minPrice; // Update best profit
}
- If current price isn't a new minimum, check if selling today would give better profit
- Only update if this profit exceeds our current best
Visual Example
Input: prices = [7, 1, 5, 3, 6, 4]
Day: 0 1 2 3 4 5
Price: 7 1 5 3 6 4
↓ ↓ ↓ ↓ ↓ ↓
Trace Through Algorithm:
Day | Price | Action | minPrice | maxProfit | Reasoning |
0 | 7 | New min | 7 | 0 | First price becomes minimum |
1 | 1 | New min | 1 | 0 | Found cheaper buying point |
2 | 5 | Sell check | 1 | 4 | Profit = 5-1 = 4 > 0, update |
3 | 3 | Sell check | 1 | 4 | Profit = 3-1 = 2 < 4, no update |
4 | 6 | Sell check | 1 | 5 | Profit = 6-1 = 5 > 4, update |
5 | 4 | Sell check | 1 | 5 | Profit = 4-1 = 3 < 5, no update |
Result: Maximum profit = 5 (buy at price 1, sell at price 6)
Key Insights
1. Why This Works
- Maintains chronological order: We only consider selling after buying
- Optimal substructure: At each point, we know the best profit possible up to that day
- Greedy approach: Always keep track of the lowest buying price for future opportunities
2. Why We Don't Need to Track Selling Price
// We don't need to store the actual selling price
// because we only care about the maximum profit value
3. Edge Cases Handled
- No profit possible: Returns 0 (initial value)
- Single day: No transaction possible, returns 0
- Decreasing prices: minPrice keeps updating, maxProfit stays 0
Complexity Analysis
Time Complexity: O(n)
- Single pass through the array
- Constant time operations for each element
Space Complexity: O(1)
- Only uses two extra variables regardless of input size
- No additional data structures needed
Alternative Approaches Comparison
Approach | Time | Space | Description |
Brute Force | O(n²) | O(1) | Check every buy-sell pair |
This Solution | O(n) | O(1) | Single pass with tracking |
Dynamic Programming | O(n) | O(n) | Store max profit at each day |
Common Mistakes to Avoid
Calculating profit with future minimum:
// ❌ Wrong: This violates chronological order maxProfit = futureMaxPrice - currentMinPrice;
Tracking unnecessary state:
// ❌ Unnecessary: Don't need to track max price int maxPrice = 0; // Not needed for this problem
Not handling decreasing array:
// ✅ Correct: Algorithm naturally handles this case // If prices only decrease, maxProfit remains 0
Test Cases
// Example 1: Normal case
prices = [7,1,5,3,6,4] → Output: 5
// Example 2: No profit possible
prices = [7,6,4,3,1] → Output: 0
// Example 3: Maximum at end
prices = [1,2,3,4,5] → Output: 4
// Example 4: Single element
prices = [1] → Output: 0
Conclusion
This solution elegantly solves the stock trading problem by:
- Tracking the minimum buying price as we scan left to right
- Calculating potential profit at each selling opportunity
- Maintaining the maximum profit seen so far
The beauty of this approach is its simplicity and efficiency - it naturally respects the time constraint (buy before sell) while finding the optimal solution in a single pass.
Subscribe to my newsletter
Read articles from Anni Huang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Anni Huang
Anni Huang
I’m Anni Huang, an AI researcher-in-training currently at ByteDance, specializing in LLM training operations with a coding focus. I bridge the gap between engineering execution and model performance, ensuring the quality, reliability, and timely delivery of large-scale training projects.