Given an array arr of n integers, where arr[i] represents price of the stock on the ith day. Determine the maximum profit achievable by buying and selling the stock at most once.
The stock should be purchased before selling it, and both actions cannot occur on the same day.
Input: arr = [10, 7, 5, 8, 11, 9]
Output: 6
Explanation: Buy on day 3 (price = 5) and sell on day 5 (price = 11), profit = 11 - 5 = 6.
Input: arr = [5, 4, 3, 2, 1]
Output: 0
Explanation: In this case, no transactions are made. Therefore, the maximum profit remains 0.
Input: arr = [3, 8, 1, 4, 6, 2]
As we need to find the maximum profit, the idea is to buy the stock at its lowest price and sell it at its highest price. We can attempt to sell the stock every day and determine the maximum profit achievable by selling it on that specific day. Ultimately, we return the maximum of these individual maximum profits as our answer.
To compute the maximum profit on a particular day, given the selling price, we need to identify the buying price. To maximize the profit on day, the buying price should be the lowest stock price observed from day 0 to the present day(as shown in the graph). This approach enables us to accurately track the optimal buying price for any given day.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
//Function to find maximum profit
int stockBuySell(vector<int> &arr, int n) {
int maxProfit = 0;
// Initialize mini to the first element of arr
int mini = arr[0];
// Traverse through the array
for (int i = 1; i < n; i++) {
// Calculate current profit
int curProfit = arr[i] - mini;
// Update maxProfit if curProfit is larger
maxProfit = max(maxProfit, curProfit);
// Update mini to minimum value encountered so far
mini = min(mini, arr[i]);
}
// Return the maximum profit
return maxProfit;
}
};
int main() {
vector<int> Arr = {7, 1, 5, 3, 6, 4};
int n = 6;
// Create an instance of Solution class
Solution sol;
// Call maximumProfit function and print the result
cout << "The maximum profit by selling the stock is " << sol.stockBuySell(Arr,6) << endl;
return 0;
}
import java.util.*;
class Solution {
// Function to calculate the maximum profit earned
public int stockBuySell(int[] arr, int n) {
int maxProfit = 0;
// Initialize mini to the first element of arr
int mini = arr[0];
// Traverse through the array
for (int i = 1; i < n; i++) {
// Calculate current profit
int curProfit = arr[i] - mini;
// Update maxProfit if curProfit is larger
maxProfit = Math.max(maxProfit, curProfit);
// Update mini to minimum value encountered so far
mini = Math.min(mini, arr[i]);
}
// Return the maximum profit
return maxProfit;
}
public static void main(String[] args) {
int[] Arr = {7, 1, 5, 3, 6, 4};
int n = 6;
// Create an instance of Solution class
Solution sol = new Solution();
// Call stockBuySell function and print the result
System.out.println("The maximum profit by selling the stock is " + sol.stockBuySell(Arr, n));
}
}
class Solution:
# Function to calculate the maximum profit earned
def stockBuySell(self, arr, n):
maxProfit = 0
# Initialize mini to the first element of arr
mini = arr[0]
# Traverse through the array
for i in range(1, n):
# Calculate current profit
curProfit = arr[i] - mini
# Update maxProfit if curProfit is larger
maxProfit = max(maxProfit, curProfit)
# Update mini to minimum value encountered so far
mini = min(mini, arr[i])
# Return the maximum profit
return maxProfit
if __name__ == "__main__":
Arr = [7, 1, 5, 3, 6, 4]
n = 6
# Create an instance of Solution class
sol = Solution()
# Call stockBuySell function and print the result
print("The maximum profit by selling the stock is", sol.stockBuySell(Arr, n))
class Solution {
// Function to calculate the maximum profit earned
stockBuySell(arr, n) {
let maxProfit = 0;
// Initialize mini to the first element of arr
let mini = arr[0];
// Traverse through the array
for (let i = 1; i < n; i++) {
// Calculate current profit
let curProfit = arr[i] - mini;
// Update maxProfit if curProfit is larger
maxProfit = Math.max(maxProfit, curProfit);
// Update mini to minimum value encountered so far
mini = Math.min(mini, arr[i]);
}
// Return the maximum profit
return maxProfit;
}
}
function main() {
const Arr = [7, 1, 5, 3, 6, 4];
const n = 6;
// Create an instance of Solution class
const sol = new Solution();
// Call stockBuySell function and print the result
console.log("The maximum profit by selling the stock is", sol.stockBuySell(Arr, n));
}
main();
Q: Can we use a two-pointer approach to solve this problem?
A: A two-pointer approach isn’t suitable here since we must track the minimum price seen so far rather than maintaining a left and right pointer comparison. A single pass with tracking variables is more efficient.
Q: How does this solution differ from the case where multiple transactions are allowed?
A: When multiple transactions are allowed, the approach changes. Instead of finding a single global maximum, we need to track multiple increasing segments and sum up all profitable transactions.
Q: How would the approach change if we were allowed at most two transactions?
A: A dynamic programming solution would be required. We maintain two transactions, tracking the best buy-sell pairs using two arrays (left_profit and right_profit), or optimize it using a state machine approach.
Q: Can this problem be solved using a sliding window or queue?
A: Not efficiently. A monotonic queue or sliding window is more useful when dealing with constraints on consecutive elements. Here, we need a global minimum tracking approach, which is best achieved with a single pass.