Capital Gain/Loss solution and explanation
9 more videos on this problem
LeetCode Medium 1393 Interview SQL Question with Detailed Explanation | Practice SQLEveryday Data Science · 10:31 · 9K views
LeetCode 1393: Capital Gain/Loss [SQL]Frederik Müller · 7:46 · 3K views
Leet Code SQL Problem 1393 Capital Gain/LossCloudFitness · 7:59 · 1K views
1393. Capital Gain/Loss (Leetcode Medium)Programming Live with Larry · 3:54 · 286 views
1393. Capital Gain Loss | LeetCode | SQL | Solution | Interview ProblemData Alchemist · 4:41 · 172 views
DAY 9 || 1393. Capital Gain/Loss || SQL SERIES || LeetCode || Oracle SQLCode with Sky · 6:03 · 121 views
LeetCode - 1393. Capital Gain/Loss (SQL)Chain Of Thought · 3:47 · 116 views
Leetcode SQL 1393.Capital Gain/Loss #leetcodesolution #sqlinterviewquestions #leetcodequestionsMoody Mansi😉 · 7:19 · 74 views
Solution to the problem «1393. Capital Gain/Loss» in SQL from the website leetcode.comVadim Kiselev · 4:41 · 73 views
Leetcode Problem : Capital Gain/Loss #dataengineering #sql @datadnyan #interviewDataDnyan · 9:05 · 65 views
The problem
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$.
Approach overview
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 1: Approach 1: Using a Dictionary to Track Buys and Sells
- When encountering a 'Buy', simply append the price to a list for that stock.
- When encountering a 'Sell', pair it with the earliest 'Buy' found in the list and calculate the gain or loss by subtracting the buy price from the sell price.
- Update the total capital gain/loss for that stock in the dictionary.
def calculate_capital_gain_loss(stocks):
gains = {}
for stock in stocks:
name = stock['stock_name']
operation = stock['operation']
price = stock['price']
if operation == 'Buy':
if name not in gains:
gains[name] = {'prices': [], 'net': 0}
gains[name]['prices'].append(price)
elif operation == 'Sell':
buy_price = gains[name]['prices'].pop(0)
gain_loss = price - buy_price
gains[name]['net'] += gain_loss
result = [{'stock_name': k, 'capital_gain_loss': v['net']} for k, v in gains.items()]
return resultimport java.util.*;
public List<Map<String, Object>> calculateCapitalGainLoss(List<Map<String, Object>> stocks) {
Map<String, List<Integer>> buyPrices = new HashMap<>();
Map<String, Integer> netGains = new HashMap<>();
for (Map<String, Object> stock : stocks) {
String name = (String)stock.get("stock_name");
String operation = (String)stock.get("operation");
int price = (int)stock.get("price");
if (operation.equals("Buy")) {
buyPrices.putIfAbsent(name, new LinkedList<>());
buyPrices.get(name).add(price);
} else if (operation.equals("Sell")) {
int buyPrice = buyPrices.get(name).remove(0);
int gainLoss = price - buyPrice;
netGains.put(name, netGains.getOrDefault(name, 0) + gainLoss);
}
}
List<Map<String, Object>> result = new ArrayList<>();
for (String name : netGains.keySet()) {
Map<String, Object> entry = new HashMap<>();
entry.put("stock_name", name);
entry.put("capital_gain_loss", netGains.get(name));
result.add(entry);
}
return result;
}Approach 2: Approach 2: Sorting and Calculating Gains/Losses
- Sort the operations by `operation_day` to ensure we process the transactions in order.
- As we iterate through the sorted list, maintain a running tally of buy and sell transactions per stock.
- Use a dictionary to accumulate the total gain/loss for each stock as we encounter sell operations.
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <deque>
#include <algorithm>
struct Stock {
std::string stock_name;
std::string operation;
int operation_day;
int price;
};
bool compare(Stock a, Stock b) {
return a.operation_day < b.operation_day;
}
std::vector<std::pair<std::string, int>> calculateCapitalGainLoss(std::vector<Stock> stocks) {
std::unordered_map<std::string, std::deque<int>> buyPrices;
std::unordered_map<std::string, int> netGains;
std::sort(stocks.begin(), stocks.end(), compare);
for (auto& stock : stocks) {
if (stock.operation == "Buy") {
buyPrices[stock.stock_name].push_back(stock.price);
} else if (stock.operation == "Sell") {
int buyPrice = buyPrices[stock.stock_name].front();
buyPrices[stock.stock_name].pop_front();
int gainLoss = stock.price - buyPrice;
netGains[stock.stock_name] += gainLoss;
}
}
std::vector<std::pair<std::string, int>> result;
for (const auto& pair : netGains) {
result.push_back(pair);
}
return result;
}function calculateCapitalGainLoss(stocks) {
stocks.sort((a, b) => a.operation_day - b.operation_day);
let gains = {};
for (let stock of stocks) {
let { stock_name, operation, price } = stock;
if (operation === 'Buy') {
if (!gains[stock_name]) gains[stock_name] = { prices: [], net: 0 };
gains[stock_name].prices.push(price);
} else if (operation === 'Sell') {
let buyPrice = gains[stock_name].prices.shift();
let gainLoss = price - buyPrice;
gains[stock_name].net += gainLoss;
}
}
return Object.keys(gains).map(name => ({ stock_name: name, capital_gain_loss: gains[name].net }));
}Approach 3: GROUP BY + SUM(IF())
We use GROUP BY to group the buy and sell operations of the same stock, and then use SUM(IF()) to calculate the capital gains and losses of each stock.
# Write your MySQL query statement below
SELECT
stock_name,
SUM(IF(operation = 'Buy', -price, price)) AS capital_gain_loss
FROM Stocks
GROUP BY 1;Complexity comparison
| Approach | Complexity |
|---|---|
| Approach 1: Using a Dictionary to Track Buys and Sells | Time Complexity is O(n), where n is the number of rows in the stock table, as we iterate through the list once and perform constant-time operations per row. Space Complexity is O(m), where m is the number of unique stocks in the list, since we maintain a list of prices for each stock. |
| Approach 2: Sorting and Calculating Gains/Losses | Time Complexity is O(n log n) due to the sorting of the stocks by their operation day, followed by O(n) processing time. Space Complexity is O(m) where m refers to the distinct stocks, as we maintain data structures for each stock's price history. |
| GROUP BY + SUM(IF()) | – |
Complexity analysis
| 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 |
Frequently asked questions
Is Capital Gain/Loss easy or hard?
Capital Gain/Loss is considered a medium difficulty problem mainly because it tests recognition of aggregation logic. Once you realize the result is simply total sells minus total buys per stock, the implementation becomes straightforward with linear time complexity.
Capital Gain/Loss Python/Java solution
Python solutions typically use a dictionary to accumulate profit per stock, updating values during a single pass through the data. Java implementations use a HashMap with the same logic: subtract price for Buy operations and add price for Sell operations.
How to solve Capital Gain/Loss in O(n)?
Maintain a hash map where the key is the stock name and the value is the accumulated profit. For each transaction, subtract the price if the operation is Buy and add the price if it is Sell. After processing all rows, the map directly stores the capital gain or loss for every stock.
What is the best approach for Capital Gain/Loss?
The hash map (dictionary) aggregation approach is the most efficient. Iterate through transactions and update a running balance per stock: subtract prices for Buy operations and add prices for Sell operations. This computes the final capital gain or loss in O(n) time with O(n) space.
Is Capital Gain/Loss asked at Google/Amazon/Meta?
Database aggregation problems like Capital Gain/Loss appear frequently in interviews at companies that test SQL and data processing skills. Variations involving transaction aggregation, profit calculations, and GROUP BY logic are common in backend and data engineering interviews.
What data structure is used in Capital Gain/Loss?
The most common data structure is a hash map (dictionary) keyed by stock name. It allows constant-time updates for each transaction while tracking cumulative buy and sell totals needed to compute the final gain or loss.
What is the time complexity of Capital Gain/Loss?
The optimal solution runs in O(n) time where n is the number of stock transactions. Each record is processed once and updates a hash map entry in constant time. Space complexity is O(n) in the worst case if every transaction belongs to a different stock.
