Best Time to Buy and Sell Stock: A Comprehensive Leetcode Guide

Best Time to Buy and Sell Stock: A Comprehensive Leetcode Guide

Hey there, fellow coder! Today, we're diving into a popular Leetcode problem: finding the best time to buy and sell stock. Sounds like something you'd hear on Wall Street, right? But don't worry, no suits or ties are required for this one—just some good ol' C++ code.

Problem Statement

Imagine you have an array where each element represents the stock price on a given day. Your mission, should you choose to accept it, is to find the maximum profit you can achieve by buying on one day and selling on another. Note that you can only hold one share of the stock at a time (so no fancy hedge fund strategies here!).

Let's break down the problem with a couple of different approaches and some jokes along the way. Ready? Let's go!

The Brute Force Approach: Slow and Steady

Our first approach is the classic brute force method. This one is straightforward but can be slower than a snail on a lazy Sunday.

CPP:

int maxProfit(vector<int>& arr) {
    int len = arr.size();
    int maxProfit = 0;
    for(int i = 0; i < len - 1; i++) {
        for(int j = i + 1; j < len; j++) {
            int currProfit = arr[j] - arr[i];
            if(currProfit > maxProfit)
                maxProfit = currProfit;
        }
    }
    return maxProfit;
}

Python:

def maxProfit(prices):
    max_profit = 0
    n = len(prices)
    for i in range(n - 1):
        for j in range(i + 1, n):
            profit = prices[j] - prices[i]
            if profit > max_profit:
                max_profit = profit
    return max_profit

Java:

public class Solution {
    public int maxProfit(int[] prices) {
        int maxProfit = 0;
        int len = prices.length;
        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                int profit = prices[j] - prices[i];
                if (profit > maxProfit) {
                    maxProfit = profit;
                }
            }
        }
        return maxProfit;
    }
}

JavaScript:

function maxProfit(prices) {
    let maxProfit = 0;
    let len = prices.length;
    for (let i = 0; i < len - 1; i++) {
        for (let j = i + 1; j < len; j++) {
            let profit = prices[j] - prices[i];
            if (profit > maxProfit) {
                maxProfit = profit;
            }
        }
    }
    return maxProfit;
}

Time Complexity:

  • O(n^2): Because of two nested loops, each iterating through the array. For each element i, we check every subsequent element j to calculate the profit.

Memory Complexity:

  • O(1): This approach uses a constant amount of extra space, regardless of the input size. The space used by maxProfit and the loop variables do not depend on the size of the input array.

Why It Works (But Slowly)

This approach checks every possible pair of buy and sell days. It finds the profit for each pair and keeps track of the maximum profit encountered. Simple enough, but the nested loops mean our time complexity is O(n^2). For large arrays, this method is slower than waiting for the latest season of your favorite show to drop.

The Optimized Approach: Fast and Furious

Now, let’s turbocharge our solution. This one’s faster and more efficient. Picture it like upgrading from a bicycle to a sports car.

CPP:

int maxProfit(vector<int>& arr) {
    int len = arr.size();
    int maxProfit = 0;
    int l = 0, r = l + 1;
    while (r < len) {
        if (arr[l] < arr[r]) {
            if (arr[r] - arr[l] > maxProfit)
                maxProfit = arr[r] - arr[l];
        } else
            l = r;
        r++;
    }
    return maxProfit;
}

Python:

def maxProfit(prices):
    max_profit = 0
    min_price = float('inf')
    for price in prices:
        if price < min_price:
            min_price = price
        elif price - min_price > max_profit:
            max_profit = price - min_price
    return max_profit

Java:

public class Solution {
    public int maxProfit(int[] prices) {
        int maxProfit = 0;
        int minPrice = Integer.MAX_VALUE;
        for (int price : prices) {
            if (price < minPrice) {
                minPrice = price;
            } else if (price - minPrice > maxProfit) {
                maxProfit = price - minPrice;
            }
        }
        return maxProfit;
    }
}

JavaScript:

function maxProfit(prices) {
    let maxProfit = 0;
    let minPrice = Infinity;
    for (let price of prices) {
        if (price < minPrice) {
            minPrice = price;
        } else if (price - minPrice > maxProfit) {
            maxProfit = price - minPrice;
        }
    }
    return maxProfit;
}

Time Complexity:

  • O(n): This approach iterates through the array only once with the two pointers, l and r. Each element is processed at most twice (once by r and potentially once by l).

Memory Complexity:

  • O(1): This approach also uses a constant amount of extra space. The additional space used by maxProfit, l, and r does not depend on the size of the input array.

Why It Works (And Quickly)

Here’s the magic: we use two pointers, l and r. l keeps track of the minimum stock price (the buy day), and r moves through the array to find the maximum profit.

  • If the stock price at r is higher than at l, we calculate the profit and update maxProfit if it's higher than the current max.

  • If the stock price at r is lower or equal, we move l to r because we've found a new potential buy day.

This approach runs in O(n) time, making it as fast as grabbing the last slice of pizza at a party.

Conclusion

There you have it! Two approaches to crack the "Best Time to Buy and Sell Stock" problem on Leetcode. The brute force method is easy to understand but can be slow, while the optimized approach is swift and efficient. Remember, coding is a journey, so enjoy the ride and don't forget to have some fun along the way.

Happy coding, and may your algorithms always find the max profit!