LeetCode 3626 - Find Stores with Inventory Imbalance
This problem asks us to identify stores with an inventory imbalance. Specifically, for each store, we need to compare the quantity of the most expensive product against the quantity of the cheapest product.
Difficulty: 🟡 Medium
Topics: —
Solution
Problem Understanding
This problem asks us to identify stores with an inventory imbalance. Specifically, for each store, we need to compare the quantity of the most expensive product against the quantity of the cheapest product. A store is considered imbalanced if the most expensive product has fewer units in stock than the cheapest product. Additionally, we need to calculate the imbalance ratio as cheapest_quantity / most_expensive_quantity, rounded to two decimal places. Only stores with three or more distinct products are considered, and the results must be ordered by the imbalance ratio in descending order and then by store name in ascending order.
The input consists of two tables: stores with information about each store, and inventory with details about each product in each store. The problem expects a query or algorithm that identifies the imbalanced stores and calculates the imbalance ratio, including the store name, location, and the names of the most expensive and cheapest products.
Important edge cases include stores with fewer than three products, products with the same price, or products where the most expensive product has a quantity equal to or greater than the cheapest product, which should be excluded. The solution must ensure correct rounding and handle division correctly.
Approaches
A brute-force approach would be to iterate through each store, retrieve all its products, identify the minimum and maximum prices along with their quantities, and then calculate the imbalance ratio if the criteria are met. While this works for small datasets, it can become inefficient for large inventories because it requires scanning all products for each store multiple times.
The optimal approach leverages SQL aggregation and window functions or Python/Go data structures such as dictionaries to group products by store. For each store, we determine the most expensive and cheapest products using MAX and MIN aggregation functions on the price, then retrieve the corresponding quantities. We filter stores with fewer than three products before calculating the imbalance ratio. Sorting is done on the imbalance ratio and store name as per the problem requirements.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(n*m) | O(n) | Scan each store and all its products individually |
| Optimal | O(n) | O(n) | Aggregate data per store and compute required quantities efficiently |
Here, n is the number of stores and m is the number of products per store.
Algorithm Walkthrough
- For each store, count the number of distinct products in the inventory table. Only keep stores with at least three products.
- Identify the most expensive product in each store by finding the maximum price. Retrieve both the product name and quantity for this product.
- Identify the cheapest product in each store by finding the minimum price. Retrieve both the product name and quantity for this product.
- Compare the quantities of the most expensive and cheapest products. Only keep stores where the quantity of the most expensive product is less than the quantity of the cheapest product.
- Calculate the imbalance ratio as
cheapest_quantity / most_expensive_quantityand round it to two decimal places. - Return the store details, names of the most expensive and cheapest products, and the imbalance ratio. Sort the result first by imbalance ratio in descending order, then by store name in ascending order.
Why it works: The algorithm ensures that each store considered has at least three products, directly identifies the extreme-priced products, and only selects stores meeting the imbalance condition. The grouping and aggregation guarantee correctness, and the final sort ensures the required output ordering.
Python Solution
import pandas as pd
def findStoresWithInventoryImbalance(stores: pd.DataFrame, inventory: pd.DataFrame) -> pd.DataFrame:
# Count number of distinct products per store
product_counts = inventory.groupby('store_id')['product_name'].nunique().reset_index()
product_counts = product_counts[product_counts['product_name'] >= 3]
# Filter stores with at least 3 products
inv_filtered = inventory[inventory['store_id'].isin(product_counts['store_id'])]
# Identify most expensive product per store
most_exp = inv_filtered.loc[inv_filtered.groupby('store_id')['price'].idxmax()]
most_exp = most_exp[['store_id', 'product_name', 'quantity']].rename(
columns={'product_name': 'most_exp_product', 'quantity': 'most_exp_qty'}
)
# Identify cheapest product per store
cheapest = inv_filtered.loc[inv_filtered.groupby('store_id')['price'].idxmin()]
cheapest = cheapest[['store_id', 'product_name', 'quantity']].rename(
columns={'product_name': 'cheapest_product', 'quantity': 'cheapest_qty'}
)
# Merge store info
merged = pd.merge(stores, most_exp, on='store_id')
merged = pd.merge(merged, cheapest, on='store_id')
# Filter for inventory imbalance
imbalance = merged[merged['most_exp_qty'] < merged['cheapest_qty']].copy()
imbalance['imbalance_ratio'] = (imbalance['cheapest_qty'] / imbalance['most_exp_qty']).round(2)
# Select and order columns
result = imbalance[['store_id', 'store_name', 'location', 'most_exp_product', 'cheapest_product', 'imbalance_ratio']]
result = result.sort_values(by=['imbalance_ratio', 'store_name'], ascending=[False, True]).reset_index(drop=True)
return result
Implementation Explanation: The code first filters stores with at least three products. Then, it uses groupby and idxmax/idxmin to retrieve the most expensive and cheapest products efficiently. Merging with the stores table ensures that store names and locations are included. The final filter checks for inventory imbalance and calculates the ratio, rounding to two decimal places. Sorting produces the final output in the desired order.
Go Solution
package main
import (
"fmt"
"math"
"sort"
)
type Store struct {
StoreID int
StoreName string
Location string
}
type Inventory struct {
InventoryID int
StoreID int
ProductName string
Quantity int
Price float64
}
type Result struct {
StoreID int
StoreName string
Location string
MostExpProduct string
CheapestProduct string
ImbalanceRatio float64
}
func findStoresWithInventoryImbalance(stores []Store, inventory []Inventory) []Result {
// Count products per store
productCount := make(map[int]int)
storeInventory := make(map[int][]Inventory)
for _, inv := range inventory {
productCount[inv.StoreID]++
storeInventory[inv.StoreID] = append(storeInventory[inv.StoreID], inv)
}
results := []Result{}
for _, store := range stores {
if productCount[store.StoreID] < 3 {
continue
}
products := storeInventory[store.StoreID]
var maxPriceInv, minPriceInv Inventory
maxPrice := -1.0
minPrice := math.MaxFloat64
for _, p := range products {
if p.Price > maxPrice {
maxPrice = p.Price
maxPriceInv = p
}
if p.Price < minPrice {
minPrice = p.Price
minPriceInv = p
}
}
if maxPriceInv.Quantity < minPriceInv.Quantity {
ratio := float64(minPriceInv.Quantity) / float64(maxPriceInv.Quantity)
ratio = math.Round(ratio*100) / 100
results = append(results, Result{
StoreID: store.StoreID,
StoreName: store.StoreName,
Location: store.Location,
MostExpProduct: maxPriceInv.ProductName,
CheapestProduct: minPriceInv.ProductName,
ImbalanceRatio: ratio,
})
}
}
// Sort by imbalance_ratio descending, then store_name ascending
sort.Slice(results, func(i, j int) bool {
if results[i].ImbalanceRatio == results[j].ImbalanceRatio {
return results[i].StoreName < results[j].StoreName
}
return results[i].ImbalanceRatio > results[j].ImbalanceRatio
})
return results
}
Go Implementation Notes: The Go solution uses maps to group inventories by store and count products. Since Go does not have built-in DataFrame operations, we iterate manually to find max/min priced products and calculate the imbalance ratio. Sorting is done using sort.Slice, which allows custom multi-key sorting. Care is taken with float rounding to two decimal places.
Worked Examples
Consider City Center (store_id 3):
- Products: Tablet (2 units, $499.99), Stylus (80 units, $29.99), Cover (60 units, $39.99)
- Max price product: Tablet, 2 units
- Min price product: Stylus, 80 units
- Imbalance ratio: 80 / 2 = 40.00
- Meets minimum 3 product requirement
- Included in result
For Corner Shop (store_id 4):
- Only 2 products: does not meet 3 product requirement
- Excluded
This is repeated for all stores, resulting in the output table as shown in the problem statement.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n + m) | n stores, m inventory records; each record processed once for aggregation and max/min search |
| Space | O(n + m) | Storing grouped inventories and intermediate results per store |