Watch 10 video solutions for Capital Gain/Loss, a medium level problem involving Database. This walkthrough by Everyday Data Science has 8,838 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Table: Stocks
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| stock_name | varchar |
| operation | enum |
| operation_day | int |
| price | int |
+---------------+---------+
(stock_name, operation_day) is the primary key (combination of columns with unique values) for this table.
The operation column is an ENUM (category) of type ('Sell', 'Buy')
Each row of this table indicates that the stock which has stock_name had an operation on the day operation_day with the price.
It is guaranteed that each 'Sell' operation for a stock has a corresponding 'Buy' operation in a previous day. It is also guaranteed that each 'Buy' operation for a stock has a corresponding 'Sell' operation in an upcoming day.
Write a solution to report the Capital gain/loss for each stock.
The Capital gain/loss of a stock is the total gain or loss after buying and selling the stock one or many times.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input:
Stocks table:
+---------------+-----------+---------------+--------+
| stock_name | operation | operation_day | price |
+---------------+-----------+---------------+--------+
| Leetcode | Buy | 1 | 1000 |
| Corona Masks | Buy | 2 | 10 |
| Leetcode | Sell | 5 | 9000 |
| Handbags | Buy | 17 | 30000 |
| Corona Masks | Sell | 3 | 1010 |
| Corona Masks | Buy | 4 | 1000 |
| Corona Masks | Sell | 5 | 500 |
| Corona Masks | Buy | 6 | 1000 |
| Handbags | Sell | 29 | 7000 |
| Corona Masks | Sell | 10 | 10000 |
+---------------+-----------+---------------+--------+
Output:
+---------------+-------------------+
| stock_name | capital_gain_loss |
+---------------+-------------------+
| Corona Masks | 9500 |
| Leetcode | 8000 |
| Handbags | -23000 |
+---------------+-------------------+
Explanation:
Leetcode stock was bought at day 1 for 1000$ and was sold at day 5 for 9000$. Capital gain = 9000 - 1000 = 8000$.
Handbags stock was bought at day 17 for 30000$ and was sold at day 29 for 7000$. Capital loss = 7000 - 30000 = -23000$.
Corona Masks stock was bought at day 1 for 10$ and was sold at day 3 for 1010$. It was bought again at day 4 for 1000$ and was sold at day 5 for 500$. At last, it was bought at day 6 for 1000$ and was sold at day 10 for 10000$. Capital gain/loss is the sum of capital gains/losses for each ('Buy' --> 'Sell') operation = (1010 - 10) + (500 - 1000) + (10000 - 1000) = 1000 - 500 + 9000 = 9500$.
Problem Overview: Each stock has multiple buy and sell operations recorded with a price. The goal is to compute the final capital gain or loss per stock by subtracting the total buy price from the total sell price. The result is returned per stock_name.
Approach 1: Using a Dictionary to Track Buys and Sells (O(n) time, O(n) space)
Iterate through all stock operations and track the running profit for each stock using a hash map. When you see a Buy operation, subtract the price from that stock’s total. When you see a Sell operation, add the price. The key insight: capital gain is simply sum(sell) - sum(buy), so you can update the balance incrementally as you process rows. This avoids storing every transaction and only maintains a single integer per stock. The approach relies on constant-time hash lookups using a hash table, making it efficient for large datasets.
This strategy works well when transaction order does not affect the result and you only care about aggregate profit. Each row is processed exactly once, resulting in O(n) time complexity and O(n) space complexity for the dictionary storing per-stock profit.
Approach 2: Sorting and Calculating Gains/Losses (O(n log n) time, O(1) extra space)
Another approach sorts transactions by stock_name and optionally by operation_day. After sorting, iterate through the records sequentially and accumulate buy and sell totals for the current stock. When the stock changes, compute total_sell - total_buy and store the result before resetting counters for the next stock.
The sorting step groups related transactions together, making the computation straightforward with a single pass afterward. This approach uses a sorting step followed by linear aggregation. Time complexity becomes O(n log n) due to sorting, while the processing pass is O(n). Extra space can remain O(1) if sorting is done in place.
This method is useful when the dataset is not grouped by stock and you want deterministic ordering for processing or debugging. It also mirrors how results would be computed using GROUP BY style aggregation in many database queries.
Recommended for interviews: The dictionary/hash map solution is typically preferred. It demonstrates that you recognized the problem as a simple aggregation and optimized it with constant-time updates. The sorting solution shows solid reasoning but introduces unnecessary overhead compared to the direct hash-based accumulation.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Dictionary to Track Buys and Sells | O(n) | O(n) | Best general solution when processing transactions directly and aggregating profit per stock |
| Sorting and Aggregation | O(n log n) | O(1) | Useful when transactions must be grouped or processed in sorted order |