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.
This approach leverages closures to keep track of whether the original function has been called. A closure allows the function to maintain state across calls, which in this case is whether the function should execute or return undefined.
This JavaScript solution defines a function once that takes a function fn as an argument. It uses a flag called to check if the function has been executed before. The first call executes fn and stores the result. Subsequent calls return undefined.
JavaScript
Python
Java
Time Complexity: O(1) for each call, Space Complexity: O(1), as no additional data structures are used.
In this approach, use an external flag variable to keep track of whether the function has already been executed. This approach is more language-specific where closure support is limited.
This C solution demonstrates using a structure to maintain state. The Once struct includes a function pointer and a flag called which checks for the first invocation. once_call executes only on the first call, thereafter returns an undefined equivalent.
Time Complexity: O(1) per call, Space Complexity: O(1) for state flag.
TypeScript
JavaScript
| Approach | Complexity |
|---|---|
| Use a Closure to Track Calls | Time Complexity: O(1) for each call, Space Complexity: O(1), as no additional data structures are used. |
| Flag with External State | Time Complexity: O(1) per call, Space Complexity: O(1) for state flag. |
| Default Approach | — |
| 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 |
Allow One Function Call - Leetcode 2666 - JavaScript 30-Day Challenge • NeetCodeIO • 12,702 views views
Watch 9 more video solutions →Practice Allow One Function Call with our built-in code editor and test cases.
Practice on FleetCode