Watch 10 video solutions for Allow One Function Call, a easy level problem. This walkthrough by NeetCodeIO has 12,702 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Given a function fn, return a new function that is identical to the original function except that it ensures fn is called at most once.
fn.undefined.
Example 1:
Input: fn = (a,b,c) => (a + b + c), calls = [[1,2,3],[2,3,6]]
Output: [{"calls":1,"value":6}]
Explanation:
const onceFn = once(fn);
onceFn(1, 2, 3); // 6
onceFn(2, 3, 6); // undefined, fn was not called
Example 2:
Input: fn = (a,b,c) => (a * b * c), calls = [[5,7,4],[2,3,6],[4,6,8]]
Output: [{"calls":1,"value":140}]
Explanation:
const onceFn = once(fn);
onceFn(5, 7, 4); // 140
onceFn(2, 3, 6); // undefined, fn was not called
onceFn(4, 6, 8); // undefined, fn was not called
Constraints:
calls is a valid JSON array1 <= calls.length <= 101 <= calls[i].length <= 1002 <= JSON.stringify(calls).length <= 1000Problem Overview: You need to wrap an existing function so it can be executed only once. The first call runs the original function and returns its result. Every later call must return undefined without executing the function again.
This is a classic function wrapper problem. The wrapper keeps track of whether the underlying function has already been executed. Once the first invocation happens, all later calls are ignored. The challenge is managing that state efficiently while preserving the original function's arguments.
Approach 1: Use a Closure to Track Calls (O(1) time, O(1) space)
The most common solution uses a closure that stores whether the function has already been executed. Create a boolean variable such as called inside the outer function. The returned inner function checks this flag before executing the original function. If called is false, invoke the function using the provided arguments and update the flag to true. If it is already true, simply return undefined.
This works because closures preserve access to variables from their enclosing scope even after the outer function returns. Each wrapped function instance gets its own independent state. The runtime cost is constant since each invocation performs only a flag check and possibly a single function call. This pattern is widely used in closures, higher-order functions, and JavaScript-style functional utilities.
Approach 2: Flag with External State (O(1) time, O(1) space)
Languages like C or C++ do not have built-in closures in the same way as JavaScript or Python. Instead, store the execution state in a variable outside the wrapper function or inside a small struct/object. The wrapper checks this shared flag before executing the original function pointer.
The logic is identical to the closure approach: check the flag, execute the function once, then permanently flip the flag. The difference is how the state is stored and passed around. This method appears in lower-level languages where function wrappers rely on explicit state management instead of lexical scope. It still runs in constant time with constant memory usage.
Problems like this appear frequently in API design and functional utilities where you want a side-effect to occur only once. Examples include initializing configuration, running startup logic, or protecting expensive operations.
Recommended for interviews: The closure-based approach is the expected answer in JavaScript, Python, and Java interviews. It demonstrates understanding of lexical scope, higher-order functions, and state captured inside a wrapper. Mentioning the external state approach shows awareness of how the same design works in languages without native closures. Both solutions run in O(1) time and O(1) space, but the closure version is cleaner and idiomatic for modern function design problems.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Closure to Track Calls | O(1) per call | O(1) | Best choice in JavaScript, Python, and Java where closures or lambdas can capture state |
| External State Flag | O(1) per call | O(1) | Useful in C/C++ or low-level implementations where closures are not available |