LeetCode Problem Workspace
Debounce
Create a debounced function that delays execution and cancels previous calls within a time window.
0
Topics
1
Code langs
0
Related
Practice Focus
Medium · Debounce core interview pattern
Answer-first summary
Create a debounced function that delays execution and cancels previous calls within a time window.
Ace coding interviews with Interview AiBoxInterview AiBox guidance for Debounce core interview pattern
To solve the debounce problem, create a function that delays the execution of a function by a set time, canceling previous calls if they occur within that window. The function should handle multiple calls and execute the final one after the time window passes. Use setTimeout and clearTimeout for handling the delays and cancellations.
Problem Statement
You are given a function fn and a delay time t in milliseconds. You need to return a debounced version of that function. A debounced function will delay its execution by t milliseconds and will cancel any previous calls made within that time window. The debounced function should also pass along the parameters that were passed to the original function.
For example, if t = 50ms and the function is called at 30ms, 60ms, and 100ms, the final execution of the function should happen at 150ms, passing only the parameters from the last call.
Examples
Example 1
Input: t = 50 calls = [ {"t": 50, inputs: [1]}, {"t": 75, inputs: [2]} ]
Output: [{"t": 125, inputs: [2]}]
let start = Date.now(); function log(...inputs) { console.log([Date.now() - start, inputs ]) } const dlog = debounce(log, 50); setTimeout(() => dlog(1), 50); setTimeout(() => dlog(2), 75);
The 1st call is cancelled by the 2nd call because the 2nd call occurred before 100ms The 2nd call is delayed by 50ms and executed at 125ms. The inputs were (2).
Example 2
Input: t = 20 calls = [ {"t": 50, inputs: [1]}, {"t": 100, inputs: [2]} ]
Output: [{"t": 70, inputs: [1]}, {"t": 120, inputs: [2]}]
The 1st call is delayed until 70ms. The inputs were (1). The 2nd call is delayed until 120ms. The inputs were (2).
Example 3
Input: t = 150 calls = [ {"t": 50, inputs: [1, 2]}, {"t": 300, inputs: [3, 4]}, {"t": 300, inputs: [5, 6]} ]
Output: [{"t": 200, inputs: [1,2]}, {"t": 450, inputs: [5, 6]}]
The 1st call is delayed by 150ms and ran at 200ms. The inputs were (1, 2). The 2nd call is cancelled by the 3rd call The 3rd call is delayed by 150ms and ran at 450ms. The inputs were (5, 6).
Constraints
- 0 <= t <= 1000
- 1 <= calls.length <= 10
- 0 <= calls[i].t <= 1000
- 0 <= calls[i].inputs.length <= 10
Solution Approach
Basic Debouncing
Use setTimeout to delay the execution of the function. Each time the debounced function is called, cancel any previously scheduled execution using clearTimeout and set a new timeout. This ensures only the latest call within the time window executes.
Handling Multiple Calls
For multiple calls within the debounce time, always cancel the previous timeout. When the last call is made, set the new timeout and ensure the function executes only once after the specified delay.
Passing Parameters
Ensure that the parameters passed to the debounced function are forwarded to the original function. This can be achieved by using the rest operator (...inputs) to capture the arguments.
Complexity Analysis
| Metric | Value |
|---|---|
| Time | Depends on the final approach |
| Space | Depends on the final approach |
The time complexity of the debounce function depends on the final approach, but typically the implementation involves constant time operations like setting and clearing timeouts, resulting in O(1) time complexity per call. The space complexity also depends on the number of timeouts created but is generally O(1).
What Interviewers Usually Probe
- Test how the candidate handles handling timeouts and cancellations in code.
- Look for how the candidate manages execution delays and parameter passing within the debounced function.
- Evaluate their ability to implement debouncing in a real-world scenario with correct handling of edge cases.
Common Pitfalls or Variants
Common pitfalls
- Not canceling the previous timeout correctly before setting a new one.
- Failing to pass the correct parameters to the original function.
- Incorrectly handling edge cases like multiple quick consecutive calls.
Follow-up variants
- Increase the delay time and observe how the debounced function reacts to multiple consecutive calls.
- Handle debouncing with varying time windows to optimize for different use cases.
- Extend debouncing to handle asynchronous functions or functions that return promises.
FAQ
What is the core idea behind the Debounce pattern?
Debouncing ensures a function is executed only after a specified delay, canceling any intermediate calls made within that time frame.
How does the debounce pattern optimize performance?
By delaying function calls and canceling unnecessary ones, debouncing reduces the frequency of executions, improving performance in scenarios like user input handling.
Why do we use setTimeout in debouncing?
setTimeout is used to delay the execution of the function, while clearTimeout helps cancel any pending executions within the debounce window.
How does the Debounce pattern apply to the problem on LeetCode?
In the LeetCode problem, you need to implement a debounced function that delays execution by t milliseconds and cancels earlier calls within that period.
What are common mistakes when implementing the Debounce pattern?
Common mistakes include not properly canceling previous timeouts, incorrect parameter handling, and failing to execute the function at the correct time.
Solution
Solution 1
#### TypeScript
type F = (...p: any[]) => any;
function debounce(fn: F, t: number): F {
let timeout: ReturnType<typeof setTimeout> | undefined;
return function (...args) {
if (timeout !== undefined) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn.apply(this, args);
}, t);
};
}
/**
* const log = debounce(console.log, 100);
* log('Hello'); // cancelled
* log('Hello'); // cancelled
* log('Hello'); // Logged at t=100ms
*/