Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given two integer arrays, skill and mana, of length n and m, respectively.
In a laboratory, n wizards must brew m potions in order. Each potion has a mana capacity mana[j] and must pass through all the wizards sequentially to be brewed properly. The time taken by the ith wizard on the jth potion is timeij = skill[i] * mana[j].
Since the brewing process is delicate, a potion must be passed to the next wizard immediately after the current wizard completes their work. This means the timing must be synchronized so that each wizard begins working on a potion exactly when it arrives.
Return the minimum amount of time required for the potions to be brewed properly.
Example 1:
Input: skill = [1,5,2,4], mana = [5,1,4,2]
Output: 110
Explanation:
| Potion Number | Start time | Wizard 0 done by | Wizard 1 done by | Wizard 2 done by | Wizard 3 done by |
|---|---|---|---|---|---|
| 0 | 0 | 5 | 30 | 40 | 60 |
| 1 | 52 | 53 | 58 | 60 | 64 |
| 2 | 54 | 58 | 78 | 86 | 102 |
| 3 | 86 | 88 | 98 | 102 | 110 |
As an example for why wizard 0 cannot start working on the 1st potion before time t = 52, consider the case where the wizards started preparing the 1st potion at time t = 50. At time t = 58, wizard 2 is done with the 1st potion, but wizard 3 will still be working on the 0th potion till time t = 60.
Example 2:
Input: skill = [1,1,1], mana = [1,1,1]
Output: 5
Explanation:
t = 0, and is completed by time t = 3.t = 1, and is completed by time t = 4.t = 2, and is completed by time t = 5.Example 3:
Input: skill = [1,2,3,4], mana = [1,2]
Output: 21
Constraints:
n == skill.lengthm == mana.length1 <= n, m <= 50001 <= mana[i], skill[i] <= 5000Problem summary: You are given two integer arrays, skill and mana, of length n and m, respectively. In a laboratory, n wizards must brew m potions in order. Each potion has a mana capacity mana[j] and must pass through all the wizards sequentially to be brewed properly. The time taken by the ith wizard on the jth potion is timeij = skill[i] * mana[j]. Since the brewing process is delicate, a potion must be passed to the next wizard immediately after the current wizard completes their work. This means the timing must be synchronized so that each wizard begins working on a potion exactly when it arrives. Return the minimum amount of time required for the potions to be brewed properly.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[1,5,2,4] [5,1,4,2]
[1,1,1] [1,1,1]
[1,2,3,4] [1,2]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3494: Find the Minimum Amount of Time to Brew Potions
class Solution {
public long minTime(int[] skill, int[] mana) {
int n = skill.length;
long[] f = new long[n];
for (int x : mana) {
long tot = 0;
for (int i = 0; i < n; ++i) {
tot = Math.max(tot, f[i]) + skill[i] * x;
}
f[n - 1] = tot;
for (int i = n - 2; i >= 0; --i) {
f[i] = f[i + 1] - skill[i + 1] * x;
}
}
return f[n - 1];
}
}
// Accepted solution for LeetCode #3494: Find the Minimum Amount of Time to Brew Potions
func minTime(skill []int, mana []int) int64 {
n := len(skill)
f := make([]int64, n)
for _, x := range mana {
var tot int64
for i := 0; i < n; i++ {
tot = max(tot, f[i]) + int64(skill[i])*int64(x)
}
f[n-1] = tot
for i := n - 2; i >= 0; i-- {
f[i] = f[i+1] - int64(skill[i+1])*int64(x)
}
}
return f[n-1]
}
# Accepted solution for LeetCode #3494: Find the Minimum Amount of Time to Brew Potions
class Solution:
def minTime(self, skill: List[int], mana: List[int]) -> int:
max = lambda a, b: a if a > b else b
n = len(skill)
f = [0] * n
for x in mana:
tot = 0
for i in range(n):
tot = max(tot, f[i]) + skill[i] * x
f[-1] = tot
for i in range(n - 2, -1, -1):
f[i] = f[i + 1] - skill[i + 1] * x
return f[-1]
// Accepted solution for LeetCode #3494: Find the Minimum Amount of Time to Brew Potions
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3494: Find the Minimum Amount of Time to Brew Potions
// class Solution {
// public long minTime(int[] skill, int[] mana) {
// int n = skill.length;
// long[] f = new long[n];
// for (int x : mana) {
// long tot = 0;
// for (int i = 0; i < n; ++i) {
// tot = Math.max(tot, f[i]) + skill[i] * x;
// }
// f[n - 1] = tot;
// for (int i = n - 2; i >= 0; --i) {
// f[i] = f[i + 1] - skill[i + 1] * x;
// }
// }
// return f[n - 1];
// }
// }
// Accepted solution for LeetCode #3494: Find the Minimum Amount of Time to Brew Potions
function minTime(skill: number[], mana: number[]): number {
const n = skill.length;
const f: number[] = Array(n).fill(0);
for (const x of mana) {
let tot = 0;
for (let i = 0; i < n; ++i) {
tot = Math.max(tot, f[i]) + skill[i] * x;
}
f[n - 1] = tot;
for (let i = n - 2; i >= 0; --i) {
f[i] = f[i + 1] - skill[i + 1] * x;
}
}
return f[n - 1];
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.