1. Find the maximum profit from one stock purchase and one later sale.
Implement maxSingleTradeProfit(prices) in JavaScript. prices is an array of 1 through 100,000 non-negative safe integers in chronological order; duplicate prices are allowed. Choose at most one buy and one later sell, never sell before buying, and return the greatest non-negative profit; return 0 when no profitable trade exists. Do not mutate or sort the input, and invalid input is outside scope. Examples: maxSingleTradeProfit([7,1,5,3,6,4]) returns 5, while [7,6,4,3,1] returns 0. Target O(n) time and O(1) auxiliary space.
I would scan the prices from left to right and keep two values: the lowest price seen so far and the best profit found so far. For each price, I update the minimum when the price is lower. Otherwise, I calculate the profit from selling at the current price and update the best profit if it is larger. This works because the minimum always comes from the current or an earlier day. The solution takes O(n) time and O(1) auxiliary space.
See the Code while reading this explanation.
We are given stock prices in chronological order. We may buy once and sell once later. We want the largest possible profit, but we may also choose not to trade, so the answer can never be negative. The main idea is to remember the lowest price seen so far. Then each later price can be treated as a possible selling price. We compare its possible profit with the best profit found so far. This avoids checking every possible buy and sell pair and gives the required one-pass solution.
- Should I return only the maximum profit, not the buy and sell indices?
- If every possible trade gives no positive profit, should I return 0?
- Can I assume the input follows the stated constraints and does not need validation?
The input is an array called prices. It contains from 1 to 100,000 non-negative safe integers in chronological order. A buy must happen before a sell. We return only the greatest non-negative profit. We do not return the buy or sell indices. We also do not sort or change the input array.
For the example prices = [7, 1, 5, 3, 6, 4], the best trade is to buy at price 1 at index 1 and sell later at price 6 at index 4. The profit is 6 - 1 = 5, so the function returns 5.
We scan from left to right. We keep minPrice, which is the lowest price seen so far, and maxProfit, which is the largest valid profit seen so far. The central invariant is that after processing index i, minPrice is the lowest price in prices[0..i]. This means a profit calculated at the current index never uses a future buying price.
The code starts with minPrice = Infinity and maxProfit = 0. Infinity lets the first real price become the first minimum. Starting maxProfit at 0 guarantees that the returned answer is never negative. If no profitable trade exists, maxProfit remains 0.
At index 0, the price is 7. Since 7 < Infinity, minPrice becomes 7. maxProfit stays 0.
At index 1, the price is 1. Since 1 < 7, minPrice becomes 1. maxProfit stays 0.
At index 2, the price is 5. It is not a new minimum, so the possible profit is 5 - 1 = 4. Since 4 is larger than maxProfit, maxProfit becomes 4.
At index 3, the price is 3. The possible profit is 3 - 1 = 2. This is smaller than 4, so maxProfit stays 4.
At index 4, the price is 6. The possible profit is 6 - 1 = 5. This is larger than 4, so maxProfit becomes 5.
At index 5, the price is 4. The possible profit is 4 - 1 = 3. This is smaller than 5, so maxProfit stays 5.
After the loop finishes, the function returns 5.
At every index, minPrice stores the lowest price seen up to that point. Therefore, when the current price is treated as a possible sell price, minPrice gives the cheapest valid buy price available so far. The algorithm compares that valid profit with maxProfit. Because prices are processed in chronological order, the algorithm never sells before buying. Taking the largest profit over all possible selling days gives the best single-trade result.
The function creates minPrice and maxProfit, then loops through the array once. For each price, it first checks whether that price is a new minimum. If it is, minPrice is updated. Otherwise, the function calculates price - minPrice and updates maxProfit when the new profit is larger. Finally, it returns maxProfit. The array is only read, so the input is not mutated or sorted.
The loop visits each price once, so the time complexity is O(n). The algorithm stores only a fixed number of variables, so the auxiliary space complexity is O(1). A one-element array returns 0. Strictly decreasing prices return 0. Equal prices also return 0. Duplicate prices work correctly because the algorithm only tracks the smallest price seen so far and the largest valid profit.
The key insight is that for every possible selling day, we only need the cheapest price available up to that day. We therefore keep a running minimum called minPrice and a running best answer called maxProfit. The invariant is: after processing index i, minPrice is the lowest value in prices[0..i], and maxProfit is the largest valid non-negative profit found among the processed prices. This removes the need to compare every possible buy and sell pair with two nested loops.
function maxSingleTradeProfit(prices) {
// Start above every valid price so the first price becomes the first minimum.
let minPrice = Infinity;
// Start at 0 because choosing no profitable trade must return 0.
let maxProfit = 0;
// Process prices from left to right in chronological order.
for (let i = 0; i < prices.length; i++) {
const price = prices[i];
// A lower price becomes the best buying price seen so far.
if (price < minPrice) {
minPrice = price;
} else {
// Selling at the current price is valid because minPrice came from
// the current or an earlier position in the chronological scan.
const profit = price - minPrice;
// Keep the greatest non-negative profit found so far.
if (profit > maxProfit) {
maxProfit = profit;
}
}
}
// If no profitable trade exists, maxProfit remains 0.
return maxProfit;
}
// Run the same examples shown in the approved diagram.
console.log(maxSingleTradeProfit([7, 1, 5, 3, 6, 4])); // 5
console.log(maxSingleTradeProfit([7, 6, 4, 3, 1])); // 0Time complexity is O(n) because the algorithm goes through the prices array once. If there are n prices, each one needs only a constant amount of work. Auxiliary space is O(1) because the algorithm stores only a fixed number of values such as minPrice, maxProfit, price, and profit. The extra memory does not grow when the input gets larger.
This running-minimum pattern is useful when values arrive in order and each later value must be compared with the best earlier value. Similar logic can be used in financial analysis, time-series monitoring, and problems that ask for the largest increase from an earlier measurement to a later measurement without storing every possible pair.
This problem checks whether a candidate can replace a simple O(n^2) pair-checking idea with a one-pass solution. It tests whether you understand chronological constraints, maintain useful running state, and keep the buy before the sell. It also checks whether you handle no-profit cases, avoid unnecessary sorting or extra memory, write correct JavaScript, maintain a clear invariant, and explain the O(n) time and O(1) auxiliary space accurately.
A common mistake is comparing prices in a way that allows selling before buying. Another mistake is sorting the array, which destroys the original chronological order. Candidates may also return a negative result for decreasing prices instead of keeping maxProfit at 0. Using two nested loops is correct but takes O(n^2) time and misses the required O(n) target. Another mistake is updating the running state in the wrong order and using a future price as the buy price.
State the invariant while you code: minPrice is always the lowest price seen so far, and maxProfit is always the best valid profit seen so far. Then walk through [7, 1, 5, 3, 6, 4] and show exactly when minPrice becomes 1 and when maxProfit changes from 0 to 4 and then to 5.









