In LeetCode Store, there are n items to sell. Each item has a price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price.
You are given an integer array price where price[i] is the price of the ith item, and an integer array needs where needs[i] is the number of pieces of the ith item you want to buy.
You are also given an array special where special[i] is of size n + 1 where special[i][j] is the number of pieces of the jth item in the ith offer and special[i][n] (i.e., the last integer in the array) is the price of the ith offer.
Return the lowest price you have to pay for exactly certain items as given, where you could make optimal use of the special offers. You are not allowed to buy more items than you want, even if that would lower the overall price. You could use any of the special offers as many times as you want.
Input & Output
Example 1 — Basic Shopping
$Input:price = [2,5], special = [[3,0,5],[1,2,10]], needs = [3,2]
›Output:14
💡 Note:Use special offer [3,0,5] to buy 3 items of type 0 for $5, then buy 2 items of type 1 individually for $10. Total: 5 + 10 = 14.
Example 2 — Multiple Offers
$Input:price = [2,3,4], special = [[1,1,0,4],[2,2,1,9]], needs = [1,2,1]
›Output:11
💡 Note:Use offer [1,1,0,4] once and buy remaining items individually: 4 + 3 + 4 = 11. This is cheaper than individual prices (2+6+4=12) or other combinations.
Example 3 — No Beneficial Offers
$Input:price = [1,1], special = [[2,2,5]], needs = [2,2]
›Output:4
💡 Note:The special offer costs $5 for [2,2] but buying individually costs only $4 (2×1 + 2×1). Choose individual purchases.
The key insight is to model this as a recursive decision problem where at each state we can either use available special offers or buy items individually. Memoization is crucial to avoid recalculating the same shopping states. The optimal approach uses dynamic programming with memoization. Time: O(k × ∏needs[i]), Space: O(∏needs[i])
Common Approaches
✓
Brute Force Recursion
⏱️ Time: O(k^m)
Space: O(m)
For each state, try using each available offer (if possible) or buy items individually. Recursively explore all possibilities and return the minimum cost.
Memoization (Top-Down DP)
⏱️ Time: O(k × ∏needs[i])
Space: O(∏needs[i])
Same recursive approach as brute force, but we memoize results for each unique shopping state (needs array) to avoid recalculating the same subproblems multiple times.
Brute Force Recursion — Algorithm Steps
Step 1: Try each special offer if it doesn't exceed needs
Step 2: Recursively solve for remaining needs
Step 3: Compare with buying all items individually
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Start State
Begin with original needs [3,2]
2
Try Offers
Recursively try each valid offer combination
3
Find Minimum
Return the minimum cost across all possibilities
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
int n;
int* prices;
int** specials;
int specialsSize;
// Check if we can apply a special offer
int canApplyOffer(int* needs, int* offer) {
for (int i = 0; i < n; i++) {
if (offer[i] > needs[i]) {
return 0;
}
}
return 1;
}
// Apply a special offer to needs
void applyOffer(int* needs, int* offer, int* newNeeds) {
for (int i = 0; i < n; i++) {
newNeeds[i] = needs[i] - offer[i];
}
}
// Calculate cost of buying all items individually
int calculateDirectCost(int* needs) {
int cost = 0;
for (int i = 0; i < n; i++) {
cost += needs[i] * prices[i];
}
return cost;
}
// Recursive function to find minimum cost
int shoppingOffers(int* needs) {
// Base case: calculate direct purchase cost
int minCost = calculateDirectCost(needs);
// Try each special offer
for (int i = 0; i < specialsSize; i++) {
if (canApplyOffer(needs, specials[i])) {
// Apply this offer and recursively solve for remaining needs
int* newNeeds = (int*)malloc(n * sizeof(int));
applyOffer(needs, specials[i], newNeeds);
int offerPrice = specials[i][n]; // Last element is the offer price
int costWithOffer = offerPrice + shoppingOffers(newNeeds);
minCost = MIN(minCost, costWithOffer);
free(newNeeds);
}
}
return minCost;
}
int solution(int* price, int priceSize, int** special, int specialSize, int* specialColSize,
int* needs, int needsSize) {
n = priceSize;
prices = price;
specials = special;
specialsSize = specialSize;
return shoppingOffers(needs);
}
int main() {
char line[10000];
// Read price array
fgets(line, sizeof(line), stdin);
int price[10];
int priceSize = 0;
char* ptr = line;
while (*ptr && *ptr != '[') ptr++;
if (*ptr == '[') ptr++;
while (*ptr && *ptr != ']') {
while (*ptr == ' ' || *ptr == ',') ptr++;
if (*ptr == ']' || *ptr == '\0') break;
price[priceSize++] = (int)strtol(ptr, &ptr, 10);
}
// Read special array
fgets(line, sizeof(line), stdin);
// Count specials
int specialSize = 0;
int bracketDepth = 0;
for (int i = 0; line[i] != '\0'; i++) {
if (line[i] == '[') {
bracketDepth++;
if (bracketDepth == 2) specialSize++;
} else if (line[i] == ']') {
bracketDepth--;
}
}
// Allocate specials array
int** special = (int**)malloc(specialSize * sizeof(int*));
for (int i = 0; i < specialSize; i++) {
special[i] = (int*)malloc((priceSize + 1) * sizeof(int));
}
// Parse specials
ptr = line;
int specialIdx = 0;
bracketDepth = 0;
while (*ptr && specialIdx < specialSize) {
if (*ptr == '[') {
bracketDepth++;
if (bracketDepth == 2) {
ptr++; // Skip inner '['
// Parse priceSize + 1 numbers
for (int j = 0; j <= priceSize; j++) {
while (*ptr && (*ptr == ' ' || *ptr == ',')) ptr++;
special[specialIdx][j] = (int)strtol(ptr, &ptr, 10);
}
specialIdx++;
bracketDepth = 1;
}
} else if (*ptr == ']') {
bracketDepth--;
}
ptr++;
}
// Read needs array
fgets(line, sizeof(line), stdin);
int needs[10];
int needsSize = 0;
ptr = line;
while (*ptr && *ptr != '[') ptr++;
if (*ptr == '[') ptr++;
while (*ptr && *ptr != ']') {
while (*ptr == ' ' || *ptr == ',') ptr++;
if (*ptr == ']' || *ptr == '\0') break;
needs[needsSize++] = (int)strtol(ptr, &ptr, 10);
}
int specialColSize = priceSize + 1;
int result = solution(price, priceSize, special, specialSize, &specialColSize, needs, needsSize);
printf("%d\n", result);
// Free memory
for (int i = 0; i < specialSize; i++) {
free(special[i]);
}
free(special);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(k^m)
k offers can be used up to m times where m is max(needs), leading to exponential combinations
n
2n
✓ Linear Growth
Space Complexity
O(m)
Recursion stack depth up to maximum sum of needs
n
2n
✓ Linear Space
28.5K Views
MediumFrequency
~25 minAvg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.