Implement a debounced function (with leading option)
Company: Grayswan Ai
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Technical Screen
## Problem
Implement a `debounce` utility in JavaScript/TypeScript.
Write a function:
```ts
function debounce<T extends (...args: any[]) => any>(
func: T,
wait: number,
options?: { leading?: boolean; trailing?: boolean }
): (...args: Parameters<T>) => void
```
that returns a new function `debounced`. When `debounced` is invoked repeatedly, it delays invoking `func` until **`wait` milliseconds have elapsed since the most recent call**.
### Requirements
- By default, behave like classic trailing-edge debounce:
- `func` runs **once**, `wait` ms after the **last** call to `debounced`.
- **Follow-up:** Support *leading debounce* via `options.leading`:
- If `leading: true`, invoke `func` immediately on the first call in a burst.
- Subsequent calls within the `wait` window should not invoke `func` again.
- If `options.trailing` is supported (optional), define behavior clearly (e.g., allow trailing call even when `leading: true`).
- Preserve `this` binding and pass through the latest arguments according to your chosen semantics.
### Clarifications to handle
- `wait` is a non-negative integer.
- Assume a browser/Node environment with `setTimeout`/`clearTimeout`.
### Additional follow-up
- State the **time and space complexity** of each call to the returned debounced function.
Quick Answer: This question evaluates mastery of debouncing patterns, timer-based asynchronous control, closures, and preservation of function context and arguments in JavaScript/TypeScript, including handling of leading and trailing edge semantics.
Given call times and arguments, simulate debounce invocation times under leading/trailing options. Return [time,arg] invocations.
Constraints
- Inputs are Python literals matching the function signature.
- Return a deterministic exact-match value.
Examples
Input: ([[0,'a'],[50,'b'],[120,'c']], 100, False, True)
Expected Output: [[220, 'c']]
Explanation: Trailing debounce.
Input: ([[0,'a'],[50,'b'],[200,'c']], 100, True, False)
Expected Output: [[0, 'a'], [200, 'c']]
Explanation: Leading only.
Input: ([[0,'a'],[50,'b']], 100, True, True)
Expected Output: [[0, 'a'], [150, 'b']]
Explanation: Leading plus trailing with latest args.
Hints
- Model object-style prompts as operation streams when needed.
- Handle empty and boundary cases before the main logic.